11

この関数テンプレートを検討してください。

template<typename T>
typename soft_error<T>::type foo(T, typename hard_error<T>::type)
{ }

Tの呼び出しの最初の引数の型から型を推測した後、コンパイラは関数シグネチャのfoo()置換とインスタンス化に進みます。T

戻り型の置換が最初に実行され、単純な置換が失敗した場合、コンパイラはオーバーロードセットを計算するときにこの関数テンプレートを破棄し、他の実行可能なオーバーロード(SFINAE)を検索します。

一方、2番目の関数パラメーターの置換が最初に発生し、ハードエラーが発生した場合(たとえば、非即時コンテキストでの置換の失敗が原因)、コンパイル全体が失敗します。

質問: 関数パラメーターと戻り値の型の置換が実行される順序に保証はありますか?


注: この例は、すべての主要なコンパイラー(VC11は個別にテストされ、同じ結果が得られました)で、パラメーター型の置換の前に戻り型の置換が行われることを示しているようです。

4

1 に答える 1

14

[注:これは元々自己回答の質問を意図したものではありませんでしたが、質問を作成しているときにたまたま解決策を見つけました]


関数パラメーターと戻り値タイプの置換が実行される順序に保証はありますか?

現在の規格にはありません。

ただし、この欠陥レポートXeo提供)は、これが実際に当てはまるように意図されていることを示しています。これは、C ++ 11標準( n3485ドラフトの一部となった)のパラグラフ14.8.2/7に対して提案された新しい表現です。

置換は、関数型およびテンプレートパラメータ宣言で使用されるすべての型と式で発生します。式には、配列の境界や非型テンプレート引数として表示されるような定数式だけでなく、sizeof、decltype、および非定数式を許可するその他のコンテキスト内の一般式(つまり、非定数式)も含まれます。置換は辞書順で進行し、推論が失敗する条件が発生すると停止します。[...]

質問へのコメントでNicolBolasが正しく指摘しているように、辞書式順序は、このライブの例に示すように、パラメータータイプのに末尾のリターンタイプが置き換えられることを意味します。

于 2013-03-17T15:11:22.683 に答える