使用 enable_if 条件编译 void 参数成员方法
conditional compilation of void argument member method using enable_if
.
#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;
}
编辑:我在 jpihl 在 std::enable_if to conditionally compile a member function 的回答中找到了问题的解决方案。但是谁能解释为什么上面的方法不起作用?
#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;
}
您对 enable_if
的第一次尝试无效,因为 SFINAE 应用于重载解析
函数(或成员函数)templates,它将消除
来自重载集的函数模板的特化
专业化无法编译。
在您的第一次尝试中,成员 hello
不是成员函数 template。
它没有模板参数。它只是 class 模板的成员 function。
它的 return 类型由 enable_if
表达式表示
如果 class 模板参数 T
不是,将导致编译失败
实例化为 bool
。这不会使成员函数本身变成模板。
SFINAE 没有申请。一旦你声明 MyClass<float> myclass2
,
MyClass<T>
及其所有成员的专业化已完全确定。
该特化 的成员函数 hello
必须 实例化,
并且 T
= float
这样做的尝试肯定无法编译。
在第二次成功的尝试中,hello
是一个成员函数模板(的
class 模板)。它有一个模板参数,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>();
不编译。
.
#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;
}
编辑:我在 jpihl 在 std::enable_if to conditionally compile a member function 的回答中找到了问题的解决方案。但是谁能解释为什么上面的方法不起作用?
#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;
}
您对 enable_if
的第一次尝试无效,因为 SFINAE 应用于重载解析
函数(或成员函数)templates,它将消除
来自重载集的函数模板的特化
专业化无法编译。
在您的第一次尝试中,成员 hello
不是成员函数 template。
它没有模板参数。它只是 class 模板的成员 function。
它的 return 类型由 enable_if
表达式表示
如果 class 模板参数 T
不是,将导致编译失败
实例化为 bool
。这不会使成员函数本身变成模板。
SFINAE 没有申请。一旦你声明 MyClass<float> myclass2
,
MyClass<T>
及其所有成员的专业化已完全确定。
该特化 的成员函数 hello
必须 实例化,
并且 T
= float
这样做的尝试肯定无法编译。
在第二次成功的尝试中,hello
是一个成员函数模板(的
class 模板)。它有一个模板参数,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>();
不编译。