2016-08-16 8 views
6

C++標準14.8.2 $ 7と言う:置換が関数型で、テンプレートのパラメータ宣言で使用されているすべてのタイプと表現で発生しテンプレートの引数控除で置換はどのように機能しますか?

。式には、配列境界や非形式テンプレート引数として表示される定数式だけでなく、sizeof,decltypeなどの一般的な式(非定数式)、および非定数式を許可するその他のコンテキストが含まれます。置換は字句順に進行し、控除が失敗する条件が発生したときに停止します。 [注:例外指定の等価置換は、例外指定がインスタンス化されたときにのみ行われます。置換が無効な型または式になると、プログラムは不正です。 - エンドノート]

標準は、ここでは例を提供します。

template <class T> struct A { using X = typename T::X; }; 
template <class T> typename T::X f(typename A<T>::X); 
template <class T> void f(...) { } 
template <class T> auto g(typename A<T>::X) -> typename T::X; 
template <class T> void g(...) { } 

void h() { 
    f<int>(0); // OK, substituting return type causes deduction to fail 
    g<int>(0); // error, substituting parameter type instantiates A<int> 
} 

g<int>(0)を呼び出すことはここでエラーであるのはなぜ?トレーリングリターン型T::Xは置換に失敗しますか?テンプレート機能fgの違いは何ですか?

答えて

4

キーポイントは、A<int>年代のインスタンス化字句順に置換進み、まず、

であり、控除が失敗する条件 が

そして第二に遭遇したときに停止します直接のコンテキストの外側で、不正な形式の構造体typename T::XT == int)をインスタンス化するため、置換エラーではなくハードエラーが発生します。 [temp.deduct]/8

のみ無効なタイプと即時 関数型のコンテキストとそのテンプレートパラメータの型の式は 控除の故障につながることができます。 【:そのようなクラステンプレートの特殊化および/または関数テンプレート 特殊、暗黙的に定義された関数の生成、等 このような副作用のインスタンス などの副作用をもたらすことができる置換型 および表現の評価「即時の文脈」には含まれておらず、 プログラムが不正な形式になる可能性があります。 - エンドノート]問題のテンプレートと

、控除障害(すなわち、SFINAE)関数型結果にtypename T::Xに代入します。 typename A<T>::Xに置換するとハードエラーになります。置換は語彙順に進行するため、template <class T> typename T::X f(typename A<T>::X);の場合、最初にtypename T::Xに置換され、減算に失敗し、さらに置換が試行されません。一方、template <class T> auto g(typename A<T>::X) -> typename T::X;の場合は、最初にtypename A<T>::Xに置き換えられ、ハードエラーになります。

+0

戻り値の型は関数シグネチャの一部としてカウントされますが、パラメータはカウントされません。 – Barry

+0

@Barry戻り値の型とパラメータの両方が関数の署名の一部とみなされると思います。 – Carousel

+0

@Barryこれらは両方とも関数テンプレートの署名の一部ですが、ここでは「署名」は使用しないでください。 –

関連する問題