C ++ stl容器元素的“CopyConstructible”要求

时间:2011-06-30 08:39:20

标签: c++ stl containers copy-constructor deep-copy

关于C ++ stl容器元素的要求,标准说:元素类型应该是CopyConstructible,并且有一个CopyConstructible要求表。此外,通过各种书籍(Josuttis等),生成的副本应该“等同于”源。

我想我需要一些清晰度。什么是“等同于”?另外,我对“CopyConstructible”和“深/浅拷贝”之间的关系有点困惑。通常,复制构造函数是浅复制或深复制。那么哪一个适用于“CopyConstructible”,哪个不适用?

感谢您的任何评论!

6 个答案:

答案 0 :(得分:8)

深层或浅层复制都有效。例如,shared_ptr总是做一个浅拷贝(有一些额外的引用计数东西),你可以在容器中使用它们就好了。这取决于复制操作的语义。

等效意味着您的程序不应该取决于它是使用原件还是副本。

答案 1 :(得分:6)

如果你把东西放进一个容器里,当你找回它时,你会得到一些等同于的东西。只要这对你的对象有意义,那么你就会得到一些东西从容器中有用。

这是浅层复制还是深层复制取决于对象类型所需的语义。您的对象可能是指针式,手柄式或类似容器。它可能包含一些可变的缓存数据,您可能会或可能不会在复制操作中复制这些数据。

只要您的复制构造函数可以访问并执行您需要它来保留对象类型的语义,那么您就满足 CopyConstructible 要求。

答案 2 :(得分:2)

一般情况下,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

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

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

答案 3 :(得分:1)

认为“复制构造函数执行深拷贝或浅拷贝”是略有限制的,并且是一种红色鲱鱼。

虽然确实如此,根据您的对象存储为成员的内容,您可能需要进行一些深度复制以获得等效性,就类型的接口而言,它不会真的很重要如何你执行了复制...只要你做了执行复制,你就得到了一个等效的对象。

如果A等同于B,那么对于设计合理的类型A==B

整个要求只是说:“元素类型必须是可复制的”。所有其余的都归结为通常的写一个正确的复制构造函数。

答案 4 :(得分:0)

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

第二个概念是等价的概念,当你在容器中使用一个对象时,它会被复制,并且执行的副本数量是未知的 - 实现可能只复制一次到在内部存储它,或者它可能在内部制作多个副本。 想要的是能够从容器中提取元素并使用它就像它是原始对象一样,这里是等价的来源:第n个您提取的副本等同于您插入的对象。

复制的概念与等价直接相关,具体取决于您建模的域,等效可能需要复制,并且根据其他约束,您可能必须选择其中一个 - 只要在您的域中它们是相同的 - 或者甚至可能是中间选项,执行部分深度复制,或者根本不复制某些成员。

答案 5 :(得分:-1)

相关文章:What is the difference between equality and equivalence?

修改为“非评论”。

等同意味着“所有意图和目的都相同”。例如:1.0001和1永远不会相等,但在某些情况下它们是等价的。这是一般性答案。

本书的含义是复制的对象必须满足strict weak ordering condition原始对象:copy < original == false && original < copy == false