在模板参数中通过SFINAE选择构造函数
Select constructor through SFINAE in template arguments
我试图通过SFINAE选择一个构造函数,如下所示:
template<typename T>
class MyClass
{
public:
template<typename C, typename = std::enable_if_t<std::is_class<C>::value>>
MyClass(C) { }
template<typename C, typename = std::enable_if_t<std::is_pointer<C>::value>>
MyClass(C) { }
};
但是编译器报错如下:
错误C2535: 'MyClass::MyClass(C)':成员函数已定义或声明
,甚至不实例化构造函数。
我制定了一个工作但丑陋的解决方案,我不想使用,因为额外的未使用的参数:
template<typename T>
class MyWorkingClass
{
public:
template<typename C>
MyWorkingClass(C, std::enable_if_t<std::is_class<C>::value>* = nullptr) { }
template<typename C>
MyWorkingClass(C, std::enable_if_t<std::is_pointer<C>::value>* = nullptr) { }
};
这里有一个简短的用法示例:
void* ptr = nullptr;
MyClass<int> mc1(ptr);
std::vector<int> vec;
MyClass<int> mc2(vec);
// Shall raise an error
// MyClass<int> mc2(0);
性状std::is_pointer
和std::is_class
只是一个例子,原始性状更为复杂。
是否有一种方法可以通过SFINAE选择构造函数,而无需向构造函数添加另一个参数(可能非常接近第一种方法)?
问题是参数的默认值不是模板方法签名的一部分。所以你有两个相同的template<class C,class>ctor(c)
因子
template<class T>
struct MyClass {
template<class C,
std::enable_if_t<std::is_class<C>{}>* =nullptr
>
MyClass(C) { }
template<class C,
std::enable_if_t<std::is_pointer<C>{}>* =nullptr
>
MyClass(C) { }
};
这里使用依赖类型的模板值实参。它们从不冲突,因为指针模板实参的类型取决于类型实参。
再添加一个(虚拟)类型模板参数:
template <typename C
, typename = std::enable_if_t<std::is_class<C>::value>>
MyClass(C) { }
template <typename C
, typename = std::enable_if_t<std::is_pointer<C>::value>
, typename = void>
// ~~~~~~~~~~~~~~^
MyClass(C) { }
这样可能更简单:
template<typename T>
class MyClass {
public:
template<typename C, typename = std::enable_if_t<std::is_class<C>::value>>
MyClass(C) { }
template<typename C>
MyClass(C*) { }
};
并非所有这些都需要由std::enable_if_t
完成。
相关文章:
- 如何使用默认参数等选择模板专业化
- 如何(从固定列表中)选择一个数字序列,该序列将与目标数字相加
- 选择要调用的构造函数
- C++选择排序算法中的逻辑错误
- 为什么使用SFINAE而不是函数重载
- 表达式 SFINAE:如何根据类型是否包含具有一个或多个参数的函数来选择模板版本
- 使用 SFINAE 有选择地实例化模板的成员函数
- 如何使用SFINAE来选择最匹配的类型特征
- C++ 如何通过可选的typedef,使用SFINAE或其他方式选择类
- SFINAE:编译器不选择专用模板类
- 在 C++11 中使用 SFINAE 在具有相同签名的两个函数之间进行选择
- SFINAE 过载选择有或没有操作员<<
- 使用 SFINAE 在 Clase 模板中选择不同的方法实现
- 我可以使用 SFINAE 有选择地定义模板类中的成员变量吗?
- 在模板参数中通过SFINAE选择构造函数
- 成员函数模板选择和SFINAE
- 使用SFINAE根据函数是否存在特定的过载来选择函数
- 使用SFINAE选择要实现的接口
- 如何在C++11中使用SFINAE从多个选项中选择构造函数
- 如何使用 sfinae 选择构造函数