马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
有时候,(别问,问就是写variant的时候),会为它添加一个模板化的带参构造函数:struct Test{
template <typename T>
Test (T&& t){
//....
}
Test (const T&){
//....
}
}
这个时候,如果再为其添加复制构造函数,会发现,根本不会调用构造函数,而是进入以const Test&实例化的带参构造函数。
要解决这个问题,可以使用C++的SFINAE特性,
为带参构造函数的模板参数添加一个不使用的有默认类型的参数,且在T为Test时其会出现编译错误。
先解释一下type_trait里的相关模板: is_same_v<typename T1,typename T2>
//等同于
is_same<typename T1,typename T2>::value
//两类型是否相同
decay_t<typename T>
//等同于
decay<typename T>::type
//去掉T的所有const,volatile以及引用修辞
enable_if_t<bool b,typename T=void>
//等同于
enable_if<bool b,typename T>
//在bool为false时什么也不是,导致编译此段代码无法通过编译,实现SFINE
所以,可以把写成这样struct Test{
template <typename T,typename= enable_if_t<!is_same_v<decay_t<T>, Test>>>
Test (T&& t){
//....
}
Test (const T&){
//....
}
这样带参构造函数的模板类型为Test的时候,将无法实例化,从而不会覆盖复制构造函数和移动构造函数 |