使用VS2012的enable_if和构造函数
enable_if and constructor with VS2012
我正在尝试有条件地启用构造函数模板。对于完全兼容c++ 11的编译器,我知道如何使用额外的默认模板参数来实现这一点。然而,我需要支持VS2012,它有std::enable_if,但不支持默认的函数模板参数。
在c++ 11中,我会这样写:template<typename T>
struct Class
{
template<typename O,
typename = typename std::enable_if<std::is_convertible<O*, T*>::value>::type>
Class(O*) {}
};
我尝试了以下,但它给出了一个错误C4336和各种后续错误:
template<typename T>
struct Class
{
template <typename O>
Class(O*, typename std::enable_if<std::is_convertible<O*, T*>::value>::type *= nullptr)
{
}
};
是否有办法使这个工作与VS2012?
添加:
类的用法如下:
struct X { };
struct X2 : X { };
struct Y { };
struct Client
{
Client(Class<X> x) {}
Client(Class<Y> y) {}
};
void test() {
X2* x2;
Client client(x2); // error C2668: ambiguous call to overloaded function
// (without std::enable_if)
}
你是所以接近解决方案!
template<typename T>
struct Class
{
template <typename O>
Class(O*, typename std::enable_if<std::is_convertible<O*, T*>::value>::type * = nullptr)
{
}
};
你发现区别了吗?形参表中的*=
被解析为乘法/赋值操作符,而不是后跟默认实参的指针类型。因此,语法错误。
这是因为c++解析器被指定为在形成标记时消耗尽可能多的字符(所谓的Maximum Munch Rule)。按预期添加一个空格将它分成两个单独的标记。
恐怕,您必须使用helper构造函数(我没有找到绕过它的方法)。但是像这样的代码应该可以工作:
#include <type_traits>
template<typename T>
struct Class
{
template<typename O>
Class(O* o) { construct(o, std::integral_constant<bool, std::is_convertible<T*, O*>::value>()); }
template<class O>
void construct(O*, std::true_type ) { /* convertible */ }
template<class O>
void construct(O*, ... ) { /* not convertible */ }
};
struct X { };
struct Y : public X { };
void check() {
X x;
int i;
Class<Y> cl(&x);
Class<Y> cl1(&i);
}
从c++ 11开始,您还可以使用委托构造函数来完成此操作:
template<typename T>
class Class {
template<typename O>
Class(O *o, std::true_type) {}
template<typename O>
Class(O *o, std::false_type) {}
public:
template<typename O>
Class(O *o): Class(o, typename std::is_convertible<O*, T*>::type) {}
};
基本思想是标签调度之一,也许它在VS2012中也工作得很好。
相关文章:
- "error: no matching function for call to"构造函数错误
- C++17复制构造函数,在std::unordereded_map上进行深度复制
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- 为什么在没有显式默认构造函数的情况下,将另一个结构封装在联合中作为成员的结构不能编译
- 为什么在C++中使用私有复制构造函数与删除复制构造函数
- 选择要调用的构造函数
- 如何委托派生类使用其父构造函数?
- 构造函数正在调用一个使用当前类类型的函数
- 没有用于初始化C++中的变量模板的匹配构造函数
- 初始化具有非默认构造函数的std::数组项的更好方法
- 当从函数参数中的临时值调用复制构造函数时
- 在c++构造函数中使用随机字符串生成器
- 一对向量构造函数:初始值设定项列表与显式构造
- 从构造函数抛出异常时如何克服内存泄漏
- 我不明白为什么我声明一个空的内部结构并将其传递给构造函数
- 继承:构造函数,初始化C++11中基类的类C数组成员
- 在 if 语句中调用重载构造函数失败
- 用if-statement移动构造函数,但使用三元运算符复制构造函数
- 是否可以将if语句建立在构造函数上?
- 在c++的if语句上初始化构造函数后删除字符串