【问题标题】:ISO C++ Standard - rules regarding examining dependent base. Why?ISO C++ 标准 - 关于检查依赖库的规则。为什么?
【发布时间】:2018-08-07 09:23:49
【问题描述】:

最近我偶然发现了 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() 将被正确地解释为对基类(呃...基结构)成员函数的调用。那么,当它们是模板时,为什么不这样做呢?

(我确信这是有充分理由的,但目前我的理解有限,这似乎很烦人。我确实尝试过搜索并找到了at least one question,但没有找到“为什么” )

【问题讨论】:

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


    【解决方案1】:

    因为模板以后可能会专门化。例如

    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-&gt; 使依赖名称和依赖名称只能在实例化时查找,届时将知道必须探索的确切基础特化。

    另请参阅Two Phase Lookup

    【讨论】:

    • 好的,你定义了没有 f() 的 B。这意味着任何定义 D 的尝试都是无效的,因为没有 f() 可以调用。那么为什么不把它留在那里呢?在这种情况下让编译失败,因为它应该。 (或者通过SFINAE,从候选人名单中删除)? D 不会编译。但是,如果您将 B 专门用于浮点 (B) 并在这种情况下实现了 f(),则 D 将编译。在我看来,该名称已经 依赖。这是继承。 struct D is 一个 B. 继承 - 一种“is-a”关系。我知道我很密集,但我仍然不明白。
    • 啊,两阶段查找。我知道它必须是显而易见的。呃。取消那个。我想我现在明白了。这是我一直忽略的话题
    • @Joe 是的,两阶段查找。简而言之,它在第一阶段失败,并添加this-&gt; 将查找推迟到第二阶段。
    • @Joe - 非成员 f() 的存在会使查找变得复杂。应该将其用于B&lt;int&gt;,还是缺少的成员函数应该是一个错误?如果你不得不说this-&gt;f(),编译器就知道了。
    • Bo,我的论点是它不应该很复杂,因为模板被明确列为从暴露成员函数 f() 的模板派生而来,就像它不会因为简单、非模板结构。当然,正如宋元耀所指出的,那是在我考虑过两阶段查找之前。我想我很容易摆脱以前不知道这一点。 Visual Studio 编译器现在正在进行一些大的(而且早就应该)的一致性改进。两阶段查找显然是其中之一。启用一致性模式真是让人大开眼界。
    猜你喜欢
    • 2020-06-28
    • 2016-10-06
    • 2010-10-13
    • 2021-12-09
    • 2015-04-03
    • 2015-03-13
    • 1970-01-01
    相关资源
    最近更新 更多