我可以失去" constness"在覆盖虚函数的返回类型?

时间:2016-10-05 08:41:45

标签: c++

以下代码编译并运行,gcc或clang不会发出警告:

#include <iostream>

struct Base {
    virtual ~Base() = default;
    virtual std::string const& get() = 0;
};

struct Derived: Base {
    virtual std::string& get() override { return m; }
    std::string m;
};

int main()
{
    Derived d;
    d.get() = "Hello, World";

    Base& b = d;
    std::cout << b.get() << "\n";
}

std::string&是否与std::string const&协变?

1 个答案:

答案 0 :(得分:18)

这是在 class.virtual 中指定的,在我们看到的最新草稿(n4606)中:

  

§10.37/ 覆盖函数的返回类型应与被覆盖函数的返回类型相同   或协变与函数的类。如果函数D::f覆盖函数B::f,则返回类型   如果它们满足以下标准,则函数是协变的:

     
      
  • 都是指向类的指针,都是对类的左值引用,或者两者都是对类 111
  • 的rvalue引用   
  • 返回类型B::f中的类与返回类型D::f中的类相同,或者是返回类中返回类型的明确且可访问的直接或间接基类类型D::f
  •   
  • 指针或引用具有相同的cv限定,并且返回类型D::f中的类类型具有与返回类型{{中的类类型相同的cv-qualification或更少的cv-qualification 1}}。
  •   

具体来说,最后一点完全解决了这里的情况:覆盖类型可以丢失B::f和/或const限定符(但不能获得它们)。

注意:如上文@george所述,第8段/用于防止此操作使用不完整的类类型,但这是since fixed