C++ 默认复制分配运算符不使用';t通过is\u复制\u可分配测试 #包括 结构A{}; 结构B{ B(A&A):A(A){} //B运算符=(B常量和B)=默认值;//第1行 //B&operator=(B const&B){a=B.a;返回*this;}//第2行 A&A; }; 静态断言(std::is\u copy\u constructible::value,“”;//通过 静态断言(std::is\u copy\u assignable::value,“”;//失败 int main(){ A A; B(a); 返回0; }

C++ 默认复制分配运算符不使用';t通过is\u复制\u可分配测试 #包括 结构A{}; 结构B{ B(A&A):A(A){} //B运算符=(B常量和B)=默认值;//第1行 //B&operator=(B const&B){a=B.a;返回*this;}//第2行 A&A; }; 静态断言(std::is\u copy\u constructible::value,“”;//通过 静态断言(std::is\u copy\u assignable::value,“”;//失败 int main(){ A A; B(a); 返回0; },c++,c++14,C++,C++14,编译器:g++5.1 默认的复制构造函数可以,但默认的复制赋值操作符失败(即使第1行未注释) 但是,显式声明它(取消第2行的注释)是有效的。它是一个bug吗?不,它不是bug。您的类没有定义的复制赋值运算符,因为您有一个引用成员。如果您有一个具有引用语义的类,那么您是否希望将赋值仅从一个引用赋值到另一个引用(这会导致复制赋值被引用对象),或者该引用是否应该反弹(虽然这通常是您所希望的,但您实际上无法做到这一点)并不明显。因此,该标准并不生成默认赋值运算符,而是允许您使用所需的语义手动定义一个赋值

编译器:g++5.1

默认的复制构造函数可以,但默认的复制赋值操作符失败(即使第1行未注释)


但是,显式声明它(取消第2行的注释)是有效的。它是一个bug吗?

不,它不是bug。您的类没有定义的复制赋值运算符,因为您有一个引用成员。如果您有一个具有引用语义的类,那么您是否希望将赋值仅从一个引用赋值到另一个引用(这会导致复制赋值被引用对象),或者该引用是否应该反弹(虽然这通常是您所希望的,但您实际上无法做到这一点)并不明显。因此,该标准并不生成默认赋值运算符,而是允许您使用所需的语义手动定义一个赋值运算符。

您不能重新分配引用。@Kerrek第2行为什么有效?@Nubcase:您知道引用是什么吗?用
inta;int&r=a
你可以说
r=10
并修改
r
引用的对象,该对象与
a
的对象相同,但不能使
r
引用其他对象。@Kerrek我明白了。谢谢
#include <type_traits>

struct A {};
struct B {
  B(A& a) : a(a) {}
  //B& operator=(B const& b) = default;                  // LINE 1
  //B& operator=(B const& b) { a = b.a; return *this; }  // LINE 2

  A& a;
};

static_assert(std::is_copy_constructible<B>::value, ""); // pass
static_assert(std::is_copy_assignable<B>::value, "");    // fail

int main() {
  A a;
  B b(a);
  return 0;
}