CRTPの次の例を考えます。
template <typename T>
int foo(T* const)
{
return 0;
}
template <typename Derived>
struct Base
{
Base() : bar(foo(static_cast<Derived*>(this)) {};
int bar;
};
struct Derived1 : Base<Derived1> {};
this
ここへの変換はDerived*
有効ですか?そうではないかもしれないことを思い出しているようですが、今のところ具体的な証拠を見つけることができません。
this
この段階での「自然な」タイプはであり、ベースの構築が完了する前のアップキャスト(12.7 / 3)など、初期化中に静的にポインタをBase* const
キャストしても問題がない場合が確かにあります。this
@DeadMGは言う:
イニシャライザリストでこれを取得する標準wrtには明示的な例外があります。これは、自分自身へのポインタをサブオブジェクトに渡すためのものです。
12.6.2 / 12は言う:
[注:mem-initializerはコンストラクターのスコープで評価されるため、このポインターをmem-initializerの式リストで使用して、初期化されるオブジェクトを参照できます。—エンドノート]
Derived*
...これはへの変換が有効であると言うのに十分ではありませんが。
私の直感では、オブジェクトの初期化のこのフェーズでは、のインスタンスを指さないので、厳密に言えば、型でそのインスタンスへthis
のポインターを持っているだけDerived
でもUBです。これは、有効なポインタでもnullポインタでもないためです。Derived*
(これは、このようなアプローチに実際的な影響を与える可能性がありますが、その回答と上記の私の例では、代わりに単に書くことですべてを回避することができますstatic_cast<Derived*>(0)
。)