【问题标题】:c++ default move assignment cannot access protected base memberc++ 默认移动赋值不能访问受保护的基成员
【发布时间】:2018-05-03 08:28:09
【问题描述】:

我有一段代码在启用语言扩展的情况下使用 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++ 版本?使用 VS 2017 和 C++17 可以很好地编译。
  • GCC 和 Clang 也编译了这个。我可以看到这是 VS 2015 中的一个老错误
  • 在 VisualStudio 2015 Update 3 中无法重现编译错误
  • @Timo 我正在使用 Visual Studio Professional 版本 14.0.25431.01 Update 3 并为 C++14 进行编译。我不确定我的 Visual Studio 版本是否也告诉你底层编译器的版本。你记得禁用语言扩展吗?

标签: c++ visual-studio-2015


【解决方案1】:

我做错了什么?

什么都没有。

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

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

【讨论】:

    猜你喜欢
    • 2016-10-01
    • 2016-07-15
    • 2014-01-26
    • 2016-04-07
    • 2013-03-05
    • 2019-12-05
    • 2017-10-15
    • 2010-12-22
    相关资源
    最近更新 更多