SFINAE无法在Visual Studio 2010上使用std :: is_pointer

时间:2012-04-10 09:36:06

标签: c++ templates c++11 sfinae visual-studio-2010

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中获得预期的功能?

1 个答案:

答案 0 :(得分: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