ISO C++ 标准 - 关于检查依赖库的规则。为什么?
ISO C++ Standard - rules regarding examining dependent base. Why?
最近我偶然发现了 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() 的依赖基 class?这个禁令的理由是什么。标准给一个吗?
如果 B 和 D 都只是常规的非模板结构,则 f() 将被正确地解释为对基础 class(呃...基础结构)成员函数的调用。那么为什么当它们是模板时不这样做呢?
(我确定有一个很好的理由,但目前我的理解有限,这似乎很烦人。我确实尝试搜索这个并发现 关于它但是 none 和它的 "why")
因为模板稍后可能会专门化。例如
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。
最近我偶然发现了 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() 的依赖基 class?这个禁令的理由是什么。标准给一个吗?
如果 B 和 D 都只是常规的非模板结构,则 f() 将被正确地解释为对基础 class(呃...基础结构)成员函数的调用。那么为什么当它们是模板时不这样做呢?
(我确定有一个很好的理由,但目前我的理解有限,这似乎很烦人。我确实尝试搜索这个并发现
因为模板稍后可能会专门化。例如
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。