为什么在扩展模板参数时访问说明符被区别对待?
Why are access specifiers treated differently when expanding template parameters?
扩展问题“”。
Clang 和 GCC 都抱怨 B
无法访问 A::member
,因为它受到保护。
但是,如果询问 B
的特定实例,B
可以访问 A::member
,只有在 B<int>::type_name
的扩展期间才会出现错误。
为什么在此上下文中忽略 B
对 A
的 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
,它无法通过其名称访问其 protect
ed 成员;但应该通过其限定名称 B<T>::member
.
访问它们
扩展问题“
Clang 和 GCC 都抱怨 B
无法访问 A::member
,因为它受到保护。
但是,如果询问 B
的特定实例,B
可以访问 A::member
,只有在 B<int>::type_name
的扩展期间才会出现错误。
为什么在此上下文中忽略 B
对 A
的 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
,它无法通过其名称访问其 protect
ed 成员;但应该通过其限定名称 B<T>::member
.