gpt4 book ai didi

c++ - C++ 是否支持与 STL 兼容的不可变记录类型?

转载 作者:太空狗 更新时间:2023-10-29 23:49:34 25 4
gpt4 key购买 nike

许多语言都支持不可变类型——一旦你构造了这种类型的值,它就不能以任何方式修改。我不会偏离这些类型的好处,因为这已在别处广泛讨论。 (参见例如 http://codebetter.com/patricksmacchia/2008/01/13/immutable-types-understand-them-and-use-them/ )

我想用 C++ 创建一个轻量级的不可变记录类型。一个明显的方法是 const 所有成员。例如:

struct Coordinates {
const double x;
const double y;
};

不幸的是,以这种方式声明的类型不支持复制赋值,因此不能与 STL 容器一起使用,这是一个非常致命的缺点。我认为没有任何解决办法,但如果有人能看到,我将不胜感激。

就其值(value)而言,据我所知,C++ 将两件事混为一谈:a) 是否可以为变量分配新值,以及 b) “值”(=对象)是否可以在它们被修改后修改被 build 。例如,区别更加清晰。 Scala,其中一个有

  • val vs var:var 可以绑定(bind)一个新值,val 不能
  • 不可变和可变对象,尤其是集合

所以我可以这样写:

val val_mutable = collection.mutable.Map(1 -> "One")
val val_immutable = collection.immutable.Map(1 -> "One")
var var_mutable = collection.mutable.Map(1 -> "One")
var var_immutable = collection.immutable.Map(1 -> "One")

var 可以重新指向其他值:

//FAILS: val_immutable = collection.immutable.Map(2 -> "Two")
//FAILS: val_mutable = collection.mutable.Map(2 -> "Two")
var_mutable = collection.mutable.Map(2 -> "Two")
var_immutable = collection.immutable.Map(2 -> "Two")

可以修改可变集合:

val_mutable(2) = "Two"    
//FAILS: val_immutable(2) = "Two"
var_mutable(2) = "Two"
//FAILS: var_immutable(2) = "Two"

在 C++ 中,const 类型的数据成员使其成为不可变类型,但也无法创建该类型的“var”。没有后者,任何人都可以找到实现前者的合理轻量级方法吗? [请注意“轻量级”部分——特别是,我不想为 struct 的每个元素创建访问器函数,因为这会导致可读性大幅下降。]

最佳答案

请记住,大多数其他语言中的赋值行为类似于 C++ 中的指针重新赋值。

因此,一个 std::shared_ptr<const T> C++ 中的不可变类型与其他语言中的不可变类型具有相似的语义。

struct Coordinates {
double x;
double y;
};
std::shared_ptr<const Coordinates> p = std::make_shared<const Coordinates>(Coordinates{3.14, 42.0});
p->x *= 2; // error; pointee is immutable
p = std::make_shared<const Coordinates>(Coordinates{6.28, 42.0}); // ok

关于c++ - C++ 是否支持与 STL 兼容的不可变记录类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39459780/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com