为什么在扩展模板参数时访问说明符被区别对待?

Why are access specifiers treated differently when expanding template parameters?

扩展问题“”。

Clang 和 GCC 都抱怨 B 无法访问 A::member,因为它受到保护。

但是,如果询问 B 的特定实例,B 可以访问 A::member,只有在 B<int>::type_name 的扩展期间才会出现错误。

为什么在此上下文中忽略 BA 的 public 继承? (如果是这样的话。)

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>>();
}

他们不是。使用 B<T>::member.


问题在于,在 decltype(member) 中,编译器立即注意到 member 不在范围内;但是,在 decltype(A<T>::member) 中,编译器在模板扩展之前无法判断该成员是否受到保护。导致错误中出现(大部分)不相关的模板扩展信息堆栈。

由于 B<T> 不是 A<T>friend,它无法通过其名称访问其 protected 成员;但应该通过其限定名称 B<T>::member.

访问它们