0

今日、誰かが次の形式のコードを提示してくれました。

#include <iostream>

namespace example {
    template <typename T>
    T variable_template = T(42);
}

int main() {
    example::variable_template<int> = 10;
    std::cout << example::variable_template<int> << std::endl;
}

ここで実行されていることがわかります: http://coliru.stacked-crooked.com/a/3a786c42b5204b0a

10 はテンポラリに割り当てられているように見えるため、このコードは 42 を出力すると予想していました。名前空間内では、テンプレートは (インスタンス化ではなく) 宣言のみであるため、名前空間内で変更するデータはありません。それにもかかわらず、それは私を驚かせ、代わりに 10 を出力しました。

一時的な割り当てに関する警告も期待していましたが、それも起こりませんでした。

これは未定義の動作ですか、テンプレートの理解に欠陥がありますか、それとも何か他のことが起こっていますか?

4

1 に答える 1

4

名前空間内では、テンプレートは (インスタンス化ではなく) 宣言のみであるため、名前空間内で変更するデータはありません。

そうじゃない!

[C++14: 14.7.2/6]:クラス、関数テンプレート、または変数テンプレートの特殊化の明示的なインスタンス化は、テンプレートが定義されている名前空間に配置されます。[..]

クラス テンプレートFooがあり、インスタンス化 (たとえばFoo<int>) を参照する場合、そのインスタンス化は通常のクラスと同じように、テンプレートと同じスコープで存在します。

変数テンプレートと同じです。を参照するときはexample::variable_template<int>、その変数をテンプレートを含むスコープに「追加」します。

名前空間exampleには、 という変数が含まれますvariable_template<int>


一時的な割り当てに関する警告も期待していましたが、それも起こりませんでした。

を除いて、ここには一時的なものはありませんT(42)

于 2017-01-08T02:41:34.183 に答える