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)。)