次のクラス テンプレート '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 = {}
2 番目のステップは、#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 による他の変更には従いません。