我玩模板专业化和SFINAE。
对于以下示例,事情似乎很简单:
template <class T>
void Do(T t, typename std::enable_if<std::is_integral<T>::value >::type* = 0)
{
cout << "is integer" << endl;
}
template <class T>
void Do(T t, typename std::enable_if<std::is_floating_point<T>::value >::type* = 0)
{
cout << "is float" << endl;
}
不,我尝试过std :: is_array,但是从未使用过std :: is_array的特化。
所以我尝试了为什么is_array从不匹配:
template <int num>
void Do( int a[num])
{
cout << "int array size " << num << endl;
}
void Do( int* x)
{
cout << "int*" << endl;
}
...
int e[] = { 1,2,3 };
Do(e);
...
me 的第一个谜团是,“int a [num]”的专业化从未捕获过!函数参数的类型始终为int *。
如果我使用引用类型,我得到了“正确”的结果:
template <int num>
void Do( int (&a)[num])
{
cout << "int array size " << num << endl;
}
void Do( int* &x)
{
cout << "int*" << endl;
}
所以我的问题出现了:std :: is_array与模板函数参数结合使用是否合理?我知道
cout << boolalpha << std::is_array<decltype(e)>::value << endl;
会给我正确的结果。但手动声明模板选择使我无法添加功能。我有没有办法检测(有或没有SFINAE)函数参数的模板特化适合数组?
答案 0 :(得分:4)
我认为你自己得到它 - 如果你想在secial化中使用它们的类型,可以通过引用将数组传递给模板函数。
您希望这样做的原因是数组到指针衰减,这是模板函数参数在与参数类型匹配之前发生的少数隐式转换之一。这就是当你试图在T
中检查它是一个数组类型时DoIt
是一个指针的原因。但是,当目标类型是引用类型时,数组到指针衰减不会发生。所以,总结一下:
template <class T>
void Do(T& t, typename std::enable_if<std::is_array<T>::value >::type* = 0)
应该有用。
BTW不使用SFINAE的无聊方式
template <class T, unsigned N>
void Do(T (&t)[N])
也有效。