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

Mat*_* M. 19 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";
}
Run Code Online (Sandbox Code Playgroud)

std::string&协变带std::string const&呢?

Mat*_* M. 18

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

§10.37 /重写函数的返回类型应与被覆函数的返回类型相同,或者与函数类的协变相同.如果函数D::f覆盖函数B::f,则函数的返回类型如果满足以下条件则是协变的:

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

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


注意:正如@george上面提到的,第8段/用于防止这种情况与不完整的类类型一起使用,但这是固定的.