7
votes

I have run into a strange situation where my derived class is able to access a private member of its base class where templates are involved.


Consider this example:

class A
{
    template<typename T>
    struct a { using type = a; };
};

class B : A
{
    template<typename T>
    using type = typename a<T>::type;
};

int main(){ }

COMPILATION RESULTS:

mingw64/mingw-w64-x86_64-clang 3.9.1-3 (from MSYS2)

$ clang++ -Wall test.cpp -o test.exe -std=c++14

mingw64/mingw-w64-x86_64-gcc 6.3.0-2 (from MSYS2)

$ g++ -Wall test.cpp -o test.exe -std=c++14

Both compilers accept without error! Additionally, if you simply move B::type into something like B::b::type clang suddenly recognizes it shouldn't be accessing a private member, while g++ compiles without a problem:

class A
{
    template<typename T>
    struct a { using type = a; };
};

class B : A
{
    template<typename T>
    struct b { using type = typename a<T>::type; };
};

int main(){ }

COMPILATION RESULTS

mingw64/mingw-w64-x86_64-clang 3.9.1-3 (from MSYS2)

$ clang++ -Wall test.cpp -o test.exe -std=c++14
test.cpp:10:39: error: 'a' is a private member of 'A'
        struct b { using type = typename a<T>::type; };
                                         ^
test.cpp:4:13: note: implicitly declared private here
        struct a { using type = a; };
               ^
1 error generated.

mingw64/mingw-w64-x86_64-gcc 6.3.0-2 (from MSYS2)

$ g++ -Wall test.cpp -o test.exe -std=c++14

My question is, what is causing this behavior where a derived class sometimes has access to its base class' members, and sometimes does not, and is this expected behavior?

1

1 Answers

9
votes

My question is, what is causing this behavior where a derived class sometimes has access to its base class' members, and sometimes does not, and is this expected behavior?

A compiler bug. There's a bunch of gcc bugs related to access control in templates, this one is probably specifically address by #41437. The clang alias template bug is #15914.