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

时间:2018-02-27 16:36:51

标签: 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()’
}
  

在D :: g的定义中,符号f来自从属基数   B类 但标准C ++不允许检查依赖基础   查找满足使用f。 的声明的 类   是Visual C ++长期以来未能成功的源代码中的错误   诊断

好的,好的,我明白了。除了一件事。为什么?

为什么标准允许检查f()的依赖基类?这项禁令的理由是什么?标准是否给出了一个?

如果B和D都只是常规的非模板结构,f()将被正确地解释为对基类(er ... base struct)成员函数的调用。那么为什么当它们是模板时却没有这样做呢?

(我确信这是一个很好的理由,但目前我的理解有限,这似乎是一种烦恼。我确实尝试搜索这个并发现at least one question关于它但没有“为什么”它)

1 个答案:

答案 0 :(得分:5)

因为模板可能稍后会被专门化。 e.g。

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