Home > Enterprise >  Why are access specifiers treated differently when expanding template parameters?
Why are access specifiers treated differently when expanding template parameters?

Time:12-02

Expanding on the question "Why is decltype'ing members of the parent class forbidden if it's a template?".

Both Clang and GCC complain that B can't access A::member, because it is protected.

But, B can access A::member if a particular instance of B is asked, it's only during the expansion of B<int>::type_name that the error arises.

Why is the public inheritance of A by B ignored in this context? (If that's what's happening.)

template<typename T>
class A{
protected:
   int member;
public:
   using type_name = T;
};

template<typename T>
class B: public A<T>{
   decltype(A<T>::member) another_member;
};

template<typename T,
         typename P=typename T::type_name>
void foo(){}

// Force the instantiation of foo
void bar(){
    foo<B<int>>();
}

CodePudding user response:

They'er not. Use B<T>::member.


The trouble comes from, in decltype(member) the compiler imminently notices that member isn't in scope; however, in decltype(A<T>::member) the compiler can't tell that the member is protected until template expansion. Leading to a (mostly) unrelated stack of template expansion information in the error.

Since B<T> is not a friend of A<T> it can't access its protected members through its name; but instead should access them though its qualified name of B<T>::member.

  • Related