c++ 默认移动赋值不能访问受保护的基成员
Posted
技术标签:
【中文标题】c++ 默认移动赋值不能访问受保护的基成员【英文标题】:c++ default move assignment cannot access protected base member 【发布时间】: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 版本是否也告诉你底层编译器的版本。你记得禁用语言扩展吗? 【参考方案1】:我做错了什么?
什么都没有。
显式默认定义与编译器生成的定义完全相同。在这种情况下,它将移动分配所有基地和成员。当然,这需要您默认的那些基础和成员的移动分配运算符可以访问。由于受到保护,您的也可以访问。
这是一个 MSVC++ 错误。如果可以,请尝试更新到更高版本。
【讨论】:
以上是关于c++ 默认移动赋值不能访问受保护的基成员的主要内容,如果未能解决你的问题,请参考以下文章