下面的代码可以编译无误:
template <typename T> struct A {
void f() { this->whatever; } // whatever is not declared before
};
int main() {
A<int> a;
}
我知道这是因为 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;
}
解析模板类定义时A
, 不可能知道它的基数是什么类型,这使得 this->whatever
可能合法( B<T>
可能有一个名为 whatever
的成员)。相反,我没有看到任何潜力 this->whatever
成员函数 f
在第一个例子中是合法的在某处使用。
所以,可以 this->whatever
在第一个例子中的某些点是合法的吗?如果不是,还有其他原因吗 this
在那种情况下应该被视为依赖于类型的表达式吗?
最佳答案
您的代码“格式错误,无需诊断”,因为 A::f
从来没有有效的特化。事实上,规范说 this->whatever
既不是未知特化的成员(因为没有依赖基类),也不是当前实例化的成员(因为它没有在非依赖基类中声明,也没有在类中声明模板本身)。这还会使您的代码无效,并且再次不需要诊断(但允许)。这在 https://stackoverflow.com/a/17579889/34509 有更详细的解释
this
是类型相关的,因为您还不知道定义中的模板参数值。因此,例如 SomeOtherTemplate<decltype(*this)>
无法立即解析,而是需要等到 this
的类模板被实例化(因此在 typename
之前需要一个 SomeOtherTemplate<decltype(*this)>::type
)。
但是,仅仅因为 this
是类型相关的,并不意味着 this->whatever
也是。如上所述,该规范具有将其正确归类为无效的工具,并且实际上不会使 this->whatever
类型依赖。它说
A class member access expression ([expr.ref]) is type-dependent if the expression refers to a member of the current instantiation and the type of the referenced member is dependent, or the class member access expression refers to a member of an unknown specialization.
关于c++ - 为什么即使模板类没有基类, `this` 也是类型依赖表达式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39218851/