【问题标题】:C++ return an object with constant member variables -- assignment operator implicitly deletedC++返回一个具有常量成员变量的对象——赋值运算符隐式删除
【发布时间】:2016-02-03 23:27:55
【问题描述】:
struct MyStruct {
   const int a, b; 
   MyStruct(int a, int b): a(a), b(b) {}
}

map<int, MyStruct> m; 

m[2] = MyStruct(3, 4); // this would fail. Of course I can use m.insert( .... )
MyStruct t = m[2]; // this would not compile, because there is no assignment operator. 

我会得到以下编译错误。

[assignment operator] is implicitly deleted because the default definition would be ill-formed:

如何解决这个问题?我希望有恒定的成员变量,以避免将来意外修改

【问题讨论】:

  • MyStruct t = m[2]; 应该使用复制构造函数而不是赋值运算符。这被称为copy initialization
  • 您可以做的不是将成员变量设为 const,而是将它们设为私有。然后具有访问它们的功能。并且没有允许它们被更新的功能。
  • 您的问题不清楚。您显示的错误消息来自m[2] = MyStruct(3,4); 行。但是,您已经正确地注意到该行失败,并且您还正确地注意到您可以改用m.insertMyStruct t = m[2]; 行是一个错误,但原因完全不同,与 const 变量无关
  • operator[] 不能与映射类型没有默认构造函数的映射一起使用,因为如果不存在,它需要创建一个新条目。您必须使用 m.find 查找此地图。

标签: c++ return-value assignment-operator


【解决方案1】:

有一个自动生成的复制构造函数,相当于

MyStruct(MyStruct &s): a(s.a), b(s.b) {}

使用它来创建副本:

MyStruct t(m[2]);

【讨论】:

  • 正如 Nathan Oliver 的评论所指出的,您甚至可能不需要定义构造函数。只需MyStruct t(m[2]); 就足够了。
  • 已经有一个隐式生成的复制构造函数可以完全按照您的方式执行(除了它还可以绑定到右值),因此这种更改不会带来任何改进。
  • @M.M.更正的分配确实回答了这个问题,我在评论中指出有一个自动生成的构造函数。我已经更新了答案。
  • 鉴于 OP 的结构定义,您建议的答案也无法编译。 (正如我在对该问题的评论中所建议的那样,也许 OP 实际上并没有发布他的真实代码)
猜你喜欢
  • 2021-06-28
  • 2020-04-09
  • 2012-09-25
  • 2011-05-16
  • 2021-08-13
  • 1970-01-01
  • 1970-01-01
  • 2011-10-20
  • 2011-12-15
相关资源
最近更新 更多