variadic模板类的部分特化是否有利于非可变参数化的特化

Ben*_*son 2 c++ templates variadic-templates c++11

我想知道用于构建例如元组的经典递归模式是否应该使用一个常规模板参数或者是否需要两个.这是一个参数案例:

// Forward declaration of main tuple class template.
template<typename... Ds> class Tuple;

// Tuple class specialization for the general case
template<typename D, typename... Ds> class Tuple<D, Ds...> {
public:

    typedef D HeadType;
    typedef Tuple<Ds...> TailType;

    Tuple() {}

    Tuple(const D& head, const Ds&... ds) : mHead(head), mTail(ds...) {}

    HeadType mHead;
    TailType mTail;
};

// Sentinel one element case
template<typename D> class Tuple<D> {
public:
    typedef D HeadType;

    Tuple() {}
    Tuple(const D& d) : mHead(d) {}

    HeadType mHead;
};
Run Code Online (Sandbox Code Playgroud)

在这里你可以争辩说,当用一个模板参数实例化(直接或在递归中)时:Tuple<int>两个特化都是有效的,并且声明应该是不明确的.但是,VS2012 Nov CTP接受此代码,因此我不知道它是否正常或者编译器是否正常.我没有在标准文本中找到任何提及这种情况的段落,但它编译肯定是方便的,并且在某种程度上逻辑上说"更具体"的非变量专业化获胜.

现在,如果这不是正确的C++ 11,下面的代码是另一种选择,使用两个常规模板参数,以便1参数大小写不能选择一般的特化:

// Forward declaration of main tuple class template.
template<typename... Ds> class Tuple;

// Tuple class specialization for the general case
template<typename D, typename D2, typename... Ds> class Tuple<D, D2, Ds...> {
public:

    typedef D HeadType;
    typedef Tuple<D2, Ds...> TailType;

    Tuple() {}

    Tuple(const D& head, const D2& d2, const Ds&... ds) : mHead(head), mTail(d2, ds...) {}

    HeadType mHead;
    TailType mTail;
};

// Sentinel one element case
template<typename D> class Tuple<D> {
public:
    typedef D HeadType;

    Tuple() {}
    Tuple(const D& d) : mHead(d) {}

    HeadType mHead;
};
Run Code Online (Sandbox Code Playgroud)

遗憾的是,这不能在VS2012 Nov CTP上编译,但这肯定是一个错误:当调用第一个特化用两种类型时,ctor对mTail的调用并不理解空参数包是空的...

所以主要问题仍然是:第一个版本是否有效C++?

如果有人可以在第二种选择中查明我的错误,请执行!

Xeo*_*Xeo 5

在这里你可以争辩说,当用一个模板参数实例化(直接或在递归中)时:Tuple<int>两个特化都是有效的,并且声明应该是不明确的.

根据现行标准,是的,这应该是模棱两可的.请参阅此缺陷报告.然而,委员会表示非变量变量的排名优于可变参数,甚至依赖于现行标准.我只是方便地链接我的另一个答案,其中包含一个例子.

现在,基本上所有好的编译器都已经实现了这个DR的解析,并且它们必须,否则std::common_type将被简单地破坏(如果定义为指定的话).所以是的,从某种意义上说,编译器对你很好,但是有充分的理由.

遗憾的是,这不能在VS2012 Nov CTP上编译,但这肯定是一个错误

是的,这是一个错误,11月份的CTP是非常错误的.当我玩它时,我当晚提交了11个可变的错误(我认为还有3个decltype错误).