考虑以下类模板“X”及其部分特化。
template <class ...Types>
struct X {}; // #1
template <class T1>
struct X<T1> {}; // #2
template <class T1, class ...Types>
struct X<T1, Types...> {}; // #3
X<int> x; // #2 or #3 ?
我怀疑 X<int> 是模棱两可的。这是因为:
很明显#2 和#3 都比#1 更专业,现在比较#2 和#3。根据14.5.5.2,我们来考虑以下#2'和#3'哪个更特化。
template <class T1>
void f(X<T1>); // #2'
template <class T1, class ...Types>
void f(X<T1, Types...>); // #3'
根据14.8.2.4,第一步是使用#2'作为参数模板和#3'作为参数模板的模板参数推导。给定唯一的参数类型是 X<A1>,推导出的 T1 是 A1,Types 是空的。
A = X<A1>, P = X<T1, Types...> => T1 = A1, Types = {}
第二步是使用 #3' 作为参数模板和 #2' 作为参数模板完成的。给定唯一的参数类型是 X<A1, Args...>,根据 14.8.2.5/9(注意这一段最近由 N3281 修订),Args 被简单地忽略,推导出的 T1 为 A1,并且参数推导成功。
A = X<A1, Args...>, P = X<T1> => T1 = A1 (Args is ignored)
最终,双向论证推演成功。所以#2 和#3 一样专业。总之,X<int> 是模棱两可的。
我的问题是:“我的解释正确吗?”
如果这个解释是正确的,那么 20.9.7.6/3 中 'std::common_type' 的定义是不合适的。
template <class ...T>
struct common_type; // #1
template <class T>
struct common_type<T> // #2
{
typedef T type;
};
template <class T, class U>
struct common_type<T, U> // #3
{
typedef
decltype(true ? declval<T>() : declval<U>())
type;
};
template <class T, class U, class ...V>
struct common_type<T, U, V...> // #4
{
typedef typename
common_type<typename common_type<T, U>::type, V...>::type
type;
};
当使用 common_type<A, B> 时,#3 和 #4 是不明确的。
注意:在第一个示例中,GCC 4.7.0(快照)和 Clang 3.0 选择 #2。但是,这些编译器非常不可靠,以至于它们不遵循 N3281 的其他更改。