"CopyConstructible" C++ stl 容器元素的要求

"CopyConstructible" requirement for C++ stl container element

本文关键字:元素 CopyConstructible C++ stl      更新时间:2023-10-16

关于C++stl容器元素的需求,标准说:元素类型应该是CopyConstructable,并且有一个CopyConstructable需求表。此外,根据各种书籍(Josuttis等),生成的副本应"等同于"来源。

我想我需要澄清一下。什么是"等价"?此外,我对"可复制结构"answers"深层/浅层复制"之间的关系有点困惑。通常,复制构造函数是浅复制或深度复制。那么,哪一个适用于"CopyConstructable",哪一种不适用呢?

感谢您的评论!

深度或浅层复制都可以。例如,shared_ptr总是进行浅拷贝(带有一些额外的引用计数内容),您可以在容器中使用它们。这取决于复制操作的语义。

等效意味着你的程序不应该取决于它是与原件还是与副本一起工作。

如果你把东西放进一个容器,当你检索它时,你会得到与你放进去的东西等效的东西。只要这对你的对象有意义,你就会从容器中得到有用的东西。

这是浅拷贝还是深拷贝取决于您想要的对象类型的语义。您的对象可能类似于指针、句柄或容器。它可能包含一些可变缓存数据,您可以选择在复制操作中复制这些数据,也可以不复制。

只要您的复制构造函数是可访问的,并且做了您需要它做的事情来保留对象类型的语义,那么您就满足了CopyConstructable的要求。

通常,STL容器可能会在某些阶段,在某些类型的操作或算法中复制您的元素,因此试金石是:

Element original(....);  // construct this awesome object
original.this_and_that();  // do stuff to it until the value is perfect...
Element another(original);

你能愉快地使用another而不是original

这实际上就是CopyConstructable需求所说的:你最好能够将它复制到另一个对象中,并且仍然对结果感到满意。这并不是一个严格的限制——你只需要仔细考虑并相应地编写你的复制构造函数。

但是,重要的是,像find()这样的一些操作可能会使用==来比较元素(对于其他容器,它可能是"<"),所以如果被复制的副作用是你无法有意义地比较元素,那么你的find等可能会停止工作-也要考虑一下!(标准规定,对于容器,"==是等价关系"(23.1-5)。

虽然确实,根据对象作为成员存储的内容,您可能需要进行一些深度复制以获得等效性,但就类型的接口而言,您如何执行复制并不重要。。。只要确实执行了复制,并且最终得到了一个等价的对象。

如果A等价于B,那么对于一个适当设计的类型,A==B

整个要求只是说:"元素类型必须是可复制的"。剩下的都归结为编写一个正确的复制构造函数的常见常识。

这里讨论了几个不同的概念。CopyConstructible只要求您可以使用现有元素作为复制源来创建该类型的新元素。它与deepshall甚至等价性无关:只要允许执行复制,容器就不在乎您在复制时在做什么。

第二个概念是等价性的概念,当您在容器中使用对象时,它将被复制,并且执行的复制数量是未知的——实现可能只复制一次以在内部存储它,也可能在内部进行多个复制。想要的是能够从容器中提取元素,并将其用作原始对象,这就是等价性的作用:提取的第n个副本应等效于插入的对象。

深度浅层复制的概念与等价直接相关,根据您正在建模的领域,等价可能需要深层层拷贝,根据其他约束,您可能必须选择其中一个——只要在您的域中它们是等效的——或者甚至可能存在中间选项,即执行部分深度复制,或者根本不复制某些成员。

相关帖子:相等和等价之间的区别是什么?

编辑后将其设为"不予评论"

对等是指"在所有意图和目的上都是平等的"。例如:1.0001和1从不相等,但在某些情况下它们是相等的。这是一般的答案。

这些书的意思是,复制的对象必须满足与原始对象copy < original == false && original < copy == false的严格弱排序条件。