最近我偶然发现了 VS 2017 中的 Visual C++ 编译器一致性模式开关。我阅读了 this explanation这给出了开关如何禁止编译不符合规范的代码的以下内容
template<typename T>
struct B {
int f();
};
template<typename T>
struct D : B<T> {
int g();
};
template<typename T>
int D<T>::g() {
return f(); // error: should be ‘this->f()’
}
In the definition of D::g, the symbol f is from the dependent base class B but standard C++ does not permit examining dependent base classes when looking for declarations that satisfy the use of f. That is an error in the source code that Visual C++ has long failed to diagnose.
好的,好的,我明白了。除了一件事。为什么?
为什么标准不允许检查 f() 的依赖基类?这个禁令的理由是什么。标准给一个吗?
如果 B 和 D 都只是常规的非模板结构,则 f() 将正确地解释为对基类(呃...基结构)成员函数的调用。那么为什么当它们是模板时不这样做呢?
(我确定这是有充分理由的,但目前我的理解有限,这似乎很烦人。我确实尝试对此进行搜索并找到了关于它的 at least one question,但没有找到它的“原因” )
最佳答案
因为模板稍后可能会专门化。例如
template<typename T>
struct B {
int f();
};
template<typename T>
struct D : B<T> {
int g();
};
template<typename T>
int D<T>::g() {
return f(); // the name f won't be looked up when not knowing the exact type of T
}
template<>
struct B<int> {
// no function named f for B<int>
};
因此标准 C++ 表示不在依赖基类中查找非依赖名称。
添加 this->
使得依赖名称和依赖名称只能在实例化时查找,那时必须探索的确切基础特化将是已知的。
另请参阅 Two Phase Lookup .
关于c++ - ISO C++ 标准 - 关于检查依赖库的规则。为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49013612/