다음 코드 스 니펫을 이해하려고합니다.
스 니펫 # 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. 여기서 struct B가 불완전한 경우 스 니펫 # 2에서 불완전하지 않은 이유는 무엇입니까?
사용 된 컴파일러 플래그 : -std=c++17 -O3 -Wall -Werror
. 미리 감사드립니다 !!!
B
.. 완전하지 않습니다 ...하지만 확실 멤버는 인스턴스화되어야 할 때
struct B
인스턴스A
로B
?