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