我想知道用于构建元组的经典递归模式是否应该使用一个常规模板参数,或者是否需要两个。这是一个参数的情况:
// 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;
};
在这里,您可以争辩说,当使用一个模板参数(直接或在递归中)实例化时: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;
};
遗憾的是,这不能在 VS2012 Nov CTP 上编译,但这肯定是一个错误:当第一个特化被两种类型调用时,对 mTail 的 ctor 调用不理解空参数包是空的......
所以主要问题仍然是:第一个版本是有效的 C++ 吗?
如果有人可以在第二种选择中查明我的错误,请这样做!