次のコードスニペットを理解しようとしています
スニペット#1
template <typename T>
struct A
{
static constexpr int VB = T::VD;
};
struct B : A<B>
{
};
ここでは、gcc9もclang9もエラーをスローしません。
Q.このコードがコンパイルされるのはなぜですか?A<B>
Bから継承するときにインスタンス化していませんか?BにはVDがないので、コンパイラーはここでエラーをスローすべきではありませんか?
スニペット#2
template <typename T>
struct A
{
static constexpr auto AB = T::AD; // <- No member named AD in B
};
struct B : A<B>
{
static constexpr auto AD = 0xD;
};
この場合、gcc9は正常にコンパイルされますが、clang9は「BにADという名前のメンバーはありません」というエラーをスローします。
Q.なぜgcc9でコンパイルするのですか/なぜclang9でコンパイルしないのですか?
スニペット#3
template <typename T>
struct A
{
using TB = typename T::TD;
};
struct B : A<B>
{
using TD = int;
};
ここでは、clang9とgcc9の両方がエラーをスローします。gcc9は、「不完全な型 'struct B'の無効な使用」を示しています。
Q.構造Bがここで不完全な場合、スニペット#2で不完全でないのはなぜですか?
使用されるコンパイラフラグ:-std=c++17 -O3 -Wall -Werror
。前もって感謝します!!!
B
..不完全である...しかし、わからないメンバーがインスタンス化されなければならないとき
struct B
インスタンス化A
していませんB
か?