我有以下代码,我希望具有不同特化的 TestEnableIf 具有不同的打印功能,但它没有按计划运行,错误如下。
struct myStruct;
struct notMyStruct;
template<typename T> struct TestEnableIf
{
template<typename boost::enable_if< boost::is_same<myStruct, T>, int >::type = 0> void print()
{
std::cout << "this is my struct" << std::endl;
}
template<typename boost::enable_if< boost::is_same<notMyStruct, T>, int>::type=0> void print()
{
std::cout << "This is not my struct" << std::endl;
}
};
static void testIsSame()
{
TestEnableIf<myStruct> testEnable;
testEnable.print();
TestEnableIf<notMyStruct> testNotEnable;
testNotEnable.print();
}
../src/testBoostGeneric.h:39:90: error: no type named ‘type’ in ‘struct boost::enable_if, int>’ template, int>::type=0> void print() ^ ../src/testBoostGeneric.h: In instantiation of ‘struct TestEnableIf’: ../src/testBoostGeneric.h:53:29:
required from here ../src/testBoostGeneric.h:34:90: error: no type named ‘type’ in ‘struct boost::enable_if, int>’ template, int >::type = 0> void print()
我不明白的是,如果 sfinae 意味着特化失败不是错误,那么编译器为什么要提示失败?
最佳答案
成员函数的 SFINAE(顺便说一句,S 是“替代”,而不是“特化”)不适用于类类型参数。一个简单的解决方法是使用另一个模板参数:
template<
typename TCopy = T
typename boost::enable_if< boost::is_same<myStruct, TCopy>, int >::type = 0
> void print()
{
std::cout << "this is my struct" << std::endl;
}
我从 STL's CppCon talk 中提取了这个. TL;DW:当使用类的 T
类型参数时,编译器在实例化类模板时知道该类型是什么,并会在那个时间点检查 type
成员.由于额外的 TCopy
类型参数是函数的本地参数,编译器在函数被实例化之前无法确定,此时 SFINAE 可以跳入以影响调用的重载集。
关于C++ 模板 sfinae 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29171309/