Car*_*sel 11 c++ templates dependent-name
可以编译以下代码而不会出现错误:
template <typename T> struct A {
void f() { this->whatever; } // whatever is not declared before
};
int main() {
A<int> a;
}
Run Code Online (Sandbox Code Playgroud)
我知道这是因为this
是一个依赖于类型的表达式,它使名称查找whatever
被推迟,直到知道实际的模板参数.由于f()
在这种情况下从不使用成员函数,因此不A<T>::f
存在实例化,并且whatever
永远不会执行名称查找.
我可以理解,this
如果类模板具有依赖于类型的基类,那么它是类型相关的:
template <typename T> struct B { T whatever; };
template <typename T> struct A : B<T> {
void f() { this->whatever; }
};
int main() {
A<int> a;
}
Run Code Online (Sandbox Code Playgroud)
在解析模板类的定义时A
,不可能知道它的基类是什么,这使得this->whatever
潜在合法(B<T>
可能有一个成员命名whatever
).相反,this->whatever
一旦在f
某个地方使用成员函数,我就没有看到任何在第一个例子中合法的可能性.
那么,this->whatever
在第一个例子中的某些点可能合法吗?如果没有,this
在这种情况下是否还有其他原因应该被视为依赖于类型的表达式?
您的代码“格式错误,无需诊断”,因为A::f
. 事实上,规范说它既this->whatever
不是未知专业化的成员(因为没有依赖基类),也不是当前实例化的成员(因为它没有在非依赖基类中声明,也没有在类模板中声明)本身)。此外,这会使您的代码无效,并且同样不需要(但允许)诊断。/sf/answers/1230592261/对此进行了更详细的解释
this
是类型相关的,因为您还不知道定义中的模板参数值。因此,例如SomeOtherTemplate<decltype(*this)>
不能立即解析,而是需要等到 的类模板this
被实例化(所以你需要一个typename
before SomeOtherTemplate<decltype(*this)>::type
)。
然而,仅仅因为this
依赖于类型,并不意味着this->whatever
也是如此。如上所述,规范具有正确地将其分类为无效的工具,并且实际上也不具有类型this->whatever
依赖性。它说
如果类成员访问表达式 ([expr.ref]) 引用当前实例化的成员并且引用的成员的类型是相关的,或者类成员访问表达式引用未知成员的成员,则该表达式是类型相关的专业化。