これはテンプレートとは何の関係もありません。推定されたテンプレートパラメータではなく、T
単なるtypedefの場合、同じ結果が得られます。std::string&
#include <string>
typedef std::string& T;
T Foo(int & i)
{
return T(i);
}
int main()
{
int a = 1;
std::string & s = Foo(a);
}
ディートマーの答えは、これをさらに単純化して次のようにできることに気づきました。
#include <string>
typedef std::string& T;
int main()
{
int a = 1;
std::string & s = T(a);
}
ここT(a)
で、はキャストと同じです。(T)a
つまり(std::string&)a
、(5.4 [expr.cast]のルールに従って)const_cast
それが有効な場合(そうではない)、またはstatic_cast
有効な場合(そうでない場合)、またはstatic_cast
フォローされている場合に実行しますconst_cast
それが有効である場合(そうでない場合)、またはそれが有効である場合reinterpret_cast
(それが有効である場合)、またはそれにreinterpret_cast
続くconst_cast
場合、それが有効である場合、式は不正な形式になります。
つまり、Dietmarが言ったように、それはreinterpret_cast
、つまり、
std::string & s = reinterpret_cast<std::string&>(a);
元のコードがコンパイルされるのは非常に驚くべきことですが、上記の行と同じであるため、コンパイルが許可されています。ただし、キャストの結果を使用することは未定義の動作です。
T(a)
がキャストと同等であるという驚きを避けるために、新しいC ++ 11の統一初期化構文を使用しますT{a}
。これは常に初期化であり、キャスト式ではありません。
すばらしい質問です。調査して回答したところ、新しい知識を提供してくれたJaredCとDietmarのおかげで、以前は気づかなかった新しい落とし穴がわかりました。