clang或gcc关于此内部类成员访问是否正确?

时间:2019-01-09 20:01:33

标签: c++ gcc clang language-lawyer

以下代码可在clang上编译并运行,但在gcc上失败并显示“错误:对静态数据成员'Outer :: a'的无效使用”:

#include <functional>
#include <vector>
#include <assert.h>
#include <iostream>
#include <memory>

class Outer
{
public:
    bool a = false;

    virtual void f() = 0;

    template <typename T>
    class Inner : public T
    {
    public:
        virtual void f() override
        {
            a = true; // Note: accessed through inheritance, not through outer scope
        }
    };
};

struct Foo : Outer { };

int main()
{
    Outer::Inner<Foo> f;
    f.f();
}

在内部类中添加“ this-> a”使其可以在两个编译器上正常工作,但是我想知道什么是正确的行为以及标准对此有何看法。

有趣的是,上面的代码在工作中作为VS2017中较大代码库的一部分工作,但是当我在单独使用VS2017的情况下在家尝试时,它失败并显示与GCC相同的错误。

您可以尝试在此处进行编译:

1 个答案:

答案 0 :(得分:4)

此代码格式错误,无需诊断。因此,海湾合作委员会是正确和友好的。缺少对Clang和MSVC的诊断只是编译器质量问题。

涉及的标准规则为[temp.res]/8

  

可以在任何实例化之前检查模板的有效性。   [注意:知道哪些名称是类型名称,这样就可以检查每个模板的语法。   —注   ]   该程序格式不正确,无需进行诊断,如果:

     
      
  • [..]

  •   
  • 紧随其定义后的模板的假想实例化会由于格式不依赖模板参数或[...]

  • 而导致格式错误   

f主体中,不合格的id表达式a不依赖于任何模板参数,因此,应在模板定义时就解决该id表达式,而无需任何知识模板参数。至此,这个表达式是不正确的。


注意:(在类成员访问之外的)非限定id表达式仅当其命名该类或非依赖基数[temp.dep.type]/5的成员时,才应视为成员:< / p>

  

名称是当前实例的成员,如果它是:

     
      
  • 一种无限定名称,当查找时,它指的是该类的至少一个成员,该类是当前实例或其非依赖基类。
  •