4

検討:

void f() {
    return 5;
}

上記はエラーになります。しかし、なぜこれではないのですか?:

template <typename = void> void f() {
    return 0;
}

gcc-4.5.1 でコンパイルしています。非テンプレート関数と同じ不正な return ステートメントを実行してもエラーが発生しないように、テンプレートを使用すると違いが生じるのはなぜですか? 私が得る唯一の後退は、取得せずに関数(つまりf())を呼び出すことができないことです:

error: return-statement with a value, in function returning 'void'

それでも、void 関数テンプレートの return ステートメントを定義できる理由は何でしょうか?

ここに私が持っているコードがあります:

template <typename = void> void f() {
    return 0;
}

// pass

int main() {



}

上記のコードは、void を返す関数内のおそらく不正な return ステートメントにもかかわらず合格します。

4

3 に答える 3

10

ほとんどのチェックは、テンプレートをインスタンス化するときにのみ実行されます。

コードはある種類のテンプレート引数では正常に動作し、別の種類のテンプレート引数ではコンパイルに失敗する可能性があるため、これは通常は良いことです。テンプレートのオーバーロードがある場合、コンパイラはコンパイルに失敗した候補を無視します。 SFINAEを参照してください。

于 2012-11-06T17:03:26.750 に答える
7

あなた

template <typename = void> void f() {
    return 0;
}

int main()
{
    f<int>();
}

prog.cpp: 関数 'void f() [with = int]' 内:
prog.cpp:7:12: ここからインスタンス化されました
prog.cpp:2:12: エラー: 値を含む return-statement、' を返す関数内空所'

プログラムはまだill- formed ですが、実際にその関数をインスタンス化していないため、コンパイラはセマンティック エラー (特権) を診断しないことを選択しています。

于 2012-11-06T17:04:13.933 に答える
6

これは実装の品質の問題です。標準からの特定の引用は次のようになります。

14.6/8 [...] テンプレート定義に対して有効な特殊化を生成できず、そのテンプレートがインスタンス化されていない場合、テンプレート定義は不適切な形式であり、診断は必要ありません。[...]

つまり、そのテンプレートを使用して有効な特殊化を生成できないため、プログラムの形式が正しくありませんが、コンパイラはこれを診断する必要はありません。後でテンプレートをインスタンス化するときに、コンパイラは特殊化を生成する必要がありますが、その特殊化は無効であり、コンパイラは文句を言います。

テンプレート定義でエラーが発生することはありません。これは、コンパイラが診断を必要としないパスに従っているためです。つまり、インスタンス化で問題を無視できなくなるまで、問題を無視しています。

于 2012-11-06T17:55:06.203 に答える