非形式引数としてローカル変数を使用することはなぜ不正ですか?非typename引数としてのローカル変数
たとえば、次のコードlocal_var
は、X
の引数にすることはできません。
template<int& x> struct X {};
void f(int local_var)
{
X<local_var> x;
}
非形式引数としてローカル変数を使用することはなぜ不正ですか?非typename引数としてのローカル変数
たとえば、次のコードlocal_var
は、X
の引数にすることはできません。
template<int& x> struct X {};
void f(int local_var)
{
X<local_var> x;
}
テンプレート引数はコンパイル時に評価されなければならない、とコンパイラが実行時まで、ローカル変数のアドレスを知ることができませんので(オブジェクトへの参照をバインドするためには、コンパイラが知っている必要がありますそのオブジェクトのアドレス)。
お知らせ、C++ 11標準は、非型テンプレート引数は、段落14.3.2/1で提供することができます正確に何を伝えている:非タイプの
テンプレート引数、非鋳型テンプレートパラメータは、のいずれかでなければならない:
からテンプレートのタイプの積分または列挙型の非タイプテンプレートパラメータ、変換定数式 (5.19)のために-parameter;または
- 非タイプのテンプレートパラメータの名前。または
- 関数テンプレート と機能テンプレートIDS含む静的記憶域期間と 外部または内部結合または外部または内部リンケージを持つ関数でオブジェクトのアドレスを指定する定数式(5.19)、しかし非静的なクラスメンバを除いて、 & id-expressionと表されます。ただし、名前が関数または配列を参照する場合は省略することができます。 は対応するテンプレートパラメータが参照;または
- NULLポインタ値(4.10)に評価される定数式。または
- nullメンバポインタ値(4.11)に評価される定数式。または
- 5.3.1で説明されているように表現されたメンバーへのポインター。または
- タイプ
std::nullptr_t
のアドレス定数式。
ご覧のとおり、ローカル変数はこのリストにありません。
待ちますが、関数をテンプレート引数として渡すことができ、コンパイラは実行時までそれらのアドレスを知りません。 – Mehrdad
@Mehrdad:私はあなたに従っているのか分かりません。なぜ機能のアドレスは実行時にしかわからないのですか? –
@Mehrdad: "ローカル"(ブロックスコープの)変数は、リンケージを持たないため、Andyが引用した3番目の箇条書きで明示的に除外されています。 http://stackoverflow.com/questions/17348611/does-static-object-in-a-template-function-have-linkage/17350254#17350254 – rici
テンプレートの「値」はコンパイル時に存在する必要があります。
template<int x> struct X {};
あなたが参照をバインドするか、ここでポインタを渡していない場合でも、コンパイラはコンパイル時に渡された要素の値を知っている必要があります。
int &x
をint x
に置き換えるのはここです。約&については、正しく答えられます。私は、それがすべての型付けされていないテンプレート引数に当てはまることを指摘したかっただけです。
X<local_var> x; // will not work, local_var does not exist at compile time
X<1> x; // works since 1 is known
コンパイル時に認識されなければならない値そのものであります回答)は、参照の代わりに値の型を使用することを示唆する結論を防止します。
'template
回答ありがとうございますが、テンプレートの代わりに
あなたはどちらも間違いなく正しいです。私はそれについて簡単に編集します。 – Pixelchemist
テンプレート引数は* type *の一部です。あなたの例では 'x 'の型は何でしょうか? –