2016-03-27 9 views
5

は、与えられた次のような単純な可変個引数テンプレートコンストラクタの優先順位

template <typename T> 
struct A 
{ 
    A(T a) {} 

    template <typename ... Ts> 
    A(T a, Ts ... more) {} 
}; 

int main() 
{ 
    A<int> a(1); 
} 

A(T a)は、可変長引数テンプレートコンストラクタの代わりに呼び出されるという保証はあり、なぜstructTintとして推定することができたときに

答えて

6

あなたが探している標準のセクションは§14.8.2.4

で、型推論は失敗します。それ以外の場合は、結果の型PおよびAを使用して、14.8.2.5で説明したように控除が行われます。 P が関数パラメータパックの場合、引数テンプレートの残りの各パラメータタイプのタイプAは、 であり、関数パラメータパックの宣言子IDのタイプPと比較されます。各比較では、 パラメータパックによって拡張されたテンプレートパラメータパックの後続の位置のテンプレート引数が導出されます( )。指定された型の控除が成功すると、引数テンプレートの型は、少なくとも とみなされ、少なくともパラメータテンプレートの型と同じように特殊化されていると見なされます。

[例:

template<class... Args> void f(Args... args); // #1 
template<class T1, class... Args> void f(T1 a1, Args... args); // #2 
template<class T1, class T2> void f(T1 a1, T2 a2); // #3 
f(); // calls #1 
f(1, 2, 3); // calls #2 
f(1, 2); // calls #3; non-variadic template #3 is more 
// specialized than the variadic templates #1 and #2 

- 終了例]

+1

14.8.2.4がより特殊であるかを確認するために、2つの関数テンプレートを比較する程度です。しかし、この例の候補関数の1つは、関数テンプレートではありません。 – aschepler

+0

@aschepler完全に一致するテンプレート以外の関数を持つと、テンプレート解決を開始する必要がないということもあるので、コンパイラはこれまでこれを取得する必要はありません。同意する。これをカバーする別のセクションがあります。 –

2

同じ理由f(const int&)f(const T&)よりも一致です:A(int)は、空のリストが関数テンプレート特殊であると推測さTs...で非テンプレート関数とA(int, Ts...)です。 Aが関数のパラメータパックから転換し、Pはパラメータパックされていない場合

関連する問題