Рассмотрим следующий шаблон шаблона "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, а типы пусты.
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> неоднозначно.
Мой вопрос: "Правильно ли моя интерпретация?"
Если эта интерпретация верна, определение "std:: common_type" в 20.9.7.6/3 не подходит.
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.