我试图有条件地启用构造函数模板。使用完全符合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)
    {
    }
};


您发现差异了吗?参数列表内的*=被解析为multiplication/assignment operator,而不是指针类型,后跟默认参数。因此,语法错误。

这是因为C ++解析器在形成令牌时被指定为消耗尽可能多的字符(所谓的“最大蒙克规则”)。根据需要,添加空格会将其分为两个单独的标记。

关于c++ - VS2012的enable_if和构造函数,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/40635870/

10-13 09:31