首页 > 解决方案 > c++ 默认移动赋值不能访问受保护的基成员

问题描述

我有一段代码用启用了语言扩展的 msvc 编译,但没有禁用语言扩展。它分解为这个最小的例子:

class A
{
    protected:
    A(const A&);
    A& operator=(const A&);
    A(A&&);
    A& operator=(A&&);
};
class B : public A
{
    public:
    B& operator=(B&&);
};
inline B& B::operator=(B&&) = default; // error C2248

错误消息是

C2248 'A::A':无法访问在类 'A' 中声明的受保护成员

在第 14 行定义了移动赋值运算符。有趣的是,以下代码编译得很好:

class A
{
    protected:
    A(const A&);
    A& operator=(const A&);
    A(A&&);
    A& operator=(A&&);
};
class B : public A
{
    public:
    B& operator=(B&&) = default;
};

同样有趣的是,这只发生在 move-assignment-operator 上。B 的复制赋值操作符以及复制和移动构造函数(但不是移动赋值操作符)可以在类定义、内联和默认值之外定义,并且代码将编译。

我究竟做错了什么?

标签: c++visual-studio-2015

解决方案


我究竟做错了什么?

没有。

显式默认定义与编译器生成的定义完全相同。在这种情况下,它将移动分配所有基地和成员。当然,这需要您默认的那些基础和成员的移动分配运算符可以访问。由于受到保护,您的可以访问。

这是一个 MSVC++ 错误。如果可以,请尝试更新到更高版本。


推荐阅读