c++ - ISO C++ 标准 - 关于检查依赖库的规则。为什么?

标签 c++ templates visual-c++ visual-studio-2017 standards-compliance

最近我偶然发现了 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/

相关文章:

c++ - 使用 int 指针的 float 的位表示

python - 有什么方法可以让这个Python字符串语句更加Pythonic吗?

c++ - "invalid initialization of non-const reference of type..."clone()函数出错

visual-c++ - 如何将 GetProfileBinary 的结果保存到智能指针中?

c++ - C++编译器创建的符号表

c++ - 您的计算机缺少 tbb.dll

c++ - 修复数组未正确分配

C++ - typedef/用于函数模板

c++ - 堆栈溢出与 std::make_unique 但不是与原始指针

c++ - 一种用于 POD 的模板特化,一种用于类层次结构和其他情况下的错误?