使用Sfinae切换构造函数的麻烦
Trouble using SFINAE to switch constructors
我有两个构造函数,我想根据模板参数 yes
template <bool yes>
class Base {
public:
template<typename std::enable_if< yes, int>::type = 0>
Base() { /* yes */ }
template<typename std::enable_if<!yes, int>::type = 0>
Base() { /* no */ }
};
我感到困惑为什么会产生编译器错误,
failed requirement '!true'; 'enable_if' cannot be used to disable this declaration
在Base<true>
和
no type named 'type' in 'std::__1::enable_if<false, int>'; 'enable_if' cannot be used to disable this declaration
在Base<false>
上。我都无法找到包括此内容的其他变体,这也没有。如何根据yes
选择哪个构造函数?
这里有几个问题。首先是默认模板模板参数的语法是错误的,应该是:
template <bool yes>
class Base {
public:
template<typename T=std::enable_if< yes, int>::type>
Base() { /* yes */ }
template<typename T=std::enable_if<!yes, int>::type>
Base() { /* no */ }
};
,但这也不是可以工作的,因为默认参数值不是模板签名的一部分,因此,大概,这等同于:
template<typename T>
Base() { /* yes */ }
template<typename T>
Base() { /* no */ }
这就是两个构造师的签名对编译器的外观。两者都是具有单个参数的模板,因此出于超载分辨率的目的,两个构造函数都具有相同的签名,并且这不会比宣布两个"基础(int foo("构造函数更好。如果您声明:
您会遇到相同的错误Base(int foo=0)
和
Base(int foo=1)
构造函数。两个构造函数,都具有相同的签名。默认值不是签名的一部分。
有几种传统的黑客攻击。C 库本身中的一个常见设计模式是声明某些助手空类,并将其用作其他参数,以消除歧义不同的方法,以解决过载分辨率。例如,使用std::in_place_t
选择std::optional
构造函数的等效功能的CC_6或std::in_place_type_t
的特定重载构造函数。
在您的情况下,我们可以与委派的构造函数一起使用完全自动的占位符参数:
#include <iostream>
struct bool_true {};
struct bool_false {};
template<bool value> class bool_value;
template<>
struct bool_value<true> {
typedef bool_true type;
};
template<>
struct bool_value<false> {
typedef bool_false type;
};
template<bool v>
using bool_value_t=typename bool_value<v>::type;
template <bool yes>
class Base {
public:
Base() : Base{ bool_value_t<yes>{} } {}
Base(const bool_true &)
{
std::cout << "Yes" << std::endl;
}
Base(const bool_false &)
{
std::cout << "No" << std::endl;
}
};
int main()
{
Base<true> t;
Base<false> f;
return 0;
}
相关文章:
- "error: no matching function for call to"构造函数错误
- C++17复制构造函数,在std::unordereded_map上进行深度复制
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- 为什么在没有显式默认构造函数的情况下,将另一个结构封装在联合中作为成员的结构不能编译
- 为什么在C++中使用私有复制构造函数与删除复制构造函数
- 选择要调用的构造函数
- 如何委托派生类使用其父构造函数?
- 构造函数正在调用一个使用当前类类型的函数
- 没有用于初始化C++中的变量模板的匹配构造函数
- 初始化具有非默认构造函数的std::数组项的更好方法
- 当从函数参数中的临时值调用复制构造函数时
- 在c++构造函数中使用随机字符串生成器
- 一对向量构造函数:初始值设定项列表与显式构造
- 从构造函数抛出异常时如何克服内存泄漏
- 我不明白为什么我声明一个空的内部结构并将其传递给构造函数
- 继承:构造函数,初始化C++11中基类的类C数组成员
- 具有默认模板类型的默认构造函数的类型推导
- 使用Sfinae切换构造函数的麻烦
- Newbie到C :麻烦设置从Anothe类继承的类中的类构造函数
- 通过指针填充自定义的类 - 与构造函数的麻烦