1

SFINAE 原则不适用于 Visual Studio 2010 中看似非常简单的事情。

#include <type_traits>
#include <iostream>

struct MyStruct
{
  int value;
  MyStruct(int value = 42) : value(value) { }
  const int& getInt() const { return value; }
};

template <typename ITER_TYPE>
auto getIteratorInt(ITER_TYPE iter) ->
  typename std::enable_if
  <std::is_pointer<decltype(*iter)>::value, const int&>::type
{
  return (*iter)->getInt();
}

template <typename ITER_TYPE>
auto getIteratorInt(ITER_TYPE iter) ->
  typename std::enable_if
  <!std::is_pointer<decltype(*iter)>::value, const int&>::type
{
  return iter->getInt();
}

int main(void)
{
  MyStruct gloryInt;
  MyStruct* gloryIntPtr = &gloryInt;
  std::cout << getIteratorInt(gloryIntPtr) << std::endl;
  std::cout << getIteratorInt(&gloryIntPtr) << std::endl;
  return 0;
}

我的意图是使用std::enable_if基于 SFINAE 原则来编译正确的模板重载。(没有现有返回类型的函数将被忽略,而另一个将被编译。)这样,您可以使用指向对象的指针或双指针,而直接对象仍然是被访问的对象。

我收到以下编译错误:

main.cpp(14): error C2039: 'type' : is not a member of 'std::tr1::enable_if<_Test,_Type>'
          with
          [
              _Test=false,
              _Type=const int &
          ]
main.cpp(17): error C3646: 'type' : unknown override specifier

好吧,如果不使用 SFINAE,这是一个非常明显的错误。有没有办法在 Visual Studio 2010 中获得预期的功能?

4

1 回答 1

2

嘿,在更新其他答案之前应该检查您的个人资料页面。

类型decltype( * iter )是指int const *const &,它是对指针的引用,而不是“裸”指针。因此std::is_pointer返回一个意想不到的结果。有两种方法可以解决这个问题:

  • 从 C++03 开始​​使用std::iterator_traits,我更喜欢:

    typename std::iterator_traits< ITER_TYPE >::value_type
    
  • 使用去除可能添加的std::decay引用的元函数decltype来反映表达式的值类别

    typename std::decay< decltype( * iter ) >::type
    
于 2012-04-10T09:44:41.650 回答