#include <iostream>
#include <type_traits>
using namespace std;
template<typename T>
struct MyClass{
void hello( void) {
hello(std::is_same<T,bool>());
}
void hello(std::true_type){
cout<<"hello only for bools"<<endl;
}
};
int main(int argc, char** argv){
MyClass<bool> myclass1;
myclass1.hello();
MyClass<float> myclass2;
//myclass2.hello(); //throws error as it should
return 0;
}
我在阅读enable_if method specialization后写了上面的代码。我希望hello()方法只有在模板参数是bool并且有效时才存在。但是,当我尝试使用enable_if解决相同的问题时,我遇到了问题。我有以下代码。任何帮助表示赞赏。如果enable_if不适合此作业,通常使用什么?
#include <iostream>
#include <type_traits>
using namespace std;
template<typename T>
struct MyClass{
typename std::enable_if<std::is_same<T,bool>::value, void>::type
hello(void)
{
cout<<"hello only for bools"<<endl;
}
};
int main(int argc, char** argv){
MyClass<bool> myclass1;
myclass1.hello();
MyClass<float> myclass2;// compilation error. Don't know how to solve
//myclass2.hello(); //I want only this line to cause compilation error
return 0;
}
编辑:我在std::enable_if to conditionally compile a member function的jpihl回答中找到了我的问题的解决方案。但有人可以解释为什么以上不起作用吗?
#include <iostream>
#include <type_traits>
using namespace std;
template<typename T>
struct MyClass{
template<class Q = T>
typename std::enable_if<std::is_same<Q, bool>::value, void>::type hello()
{
cout<<"hello only for bools"<<endl;
}
};
int main(int argc, char** argv){
MyClass<bool> myclass1;
myclass1.hello();
MyClass<float> myclass2;// throws errow. Don't know how to solve
myclass2.hello(); //
return 0;
}
答案 0 :(得分:1)
enable_if
的第一次尝试不起作用,因为SFINAE适用于重载决策
功能(或成员功能)模板,它将消除
当过载集合中的函数模板的特化
专业化无法编译。
第一次尝试时,成员hello
不是成员函数模板。
它没有模板参数。它只是类模板的成员功能。
它的返回类型由enable_if
表达式表达
如果类模板参数T
不是,则会引发编译失败
实例化为bool
。这不会使成员自身成为模板。
SFINAE没有申请。一旦你宣布MyClass<float> myclass2
,就会
MyClass<T>
及其所有成员的专业化是完全确定的。
必须实例化该专业化的成员函数hello
,
并且T
= float
尝试这样做必然无法编译。
在第二次成功尝试中,hello
是成员函数模板(
一个类模板)。它有一个模板参数Q
,默认情况下为= T
。
因此,SFINAE适用,您可以按预期方式将其与enable_if
一起使用。
您可以无误地声明MyClass<float> myclass2
,因为这样做
不会强制模板成员MyClass<float>::hello<Q>
由于您只编写了hello
的一个重载,因此只有一个专门化
任何Q
选择的成员函数模板。当Q
= bool
时,那
单一专业化存活,myclass1.hello()
将存在
编译。当Q
!= bool
时,SFINAE会取消该单一专业化
并且myclass2.hello()
无法编译。
生动地说明第二种情况下SFINAE如何在瞬间运行 成员函数模板,请考虑:
MyClass<float> myclass2;
myclass2.hello<bool>();
很好;而另一方面:
MyClass<bool> myclass1;
myclass1.hello<float>();
无法编译。