问题标签 [copy-and-swap]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
2 回答
9664 浏览

c++ - 什么是复制省略,它如何优化复制和交换的习惯用法?

我正在阅读Copy and Swap

我尝试阅读有关 Copy Elision 的一些链接,但无法正确理解它的含义。有人可以解释一下这个优化是什么,特别是下面的文字是什么意思

这不仅仅是方便的问题,实际上也是一种优化。如果参数(s)绑定到左值(另一个非常量对象),则在创建参数时会自动制作对象的副本。但是,当 s 绑定到右值(临时对象,文字)时,副本通常会被省略,这样可以节省对复制构造函数和析构函数的调用。在参数被接受为 const 引用的赋值运算符的早期版本中,当引用绑定到右值时,不会发生复制省略。这会导致创建和销毁一个额外的对象。

0 投票
5 回答
423666 浏览

c++ - 什么是复制和交换成语?

这个成语是什么,应该在什么时候使用?它解决了哪些问题?使用 C++11 时习语会发生变化吗?

尽管在很多地方都提到过,但我们没有任何单一的“它是什么”问题和答案,所以在这里。以下是之前提到的地方的部分列表:

0 投票
1 回答
1948 浏览

c++ - 通过复制和交换与两个锁进行分配

借用Howard Hinnant 的示例并将其修改为使用复制和交换,这 op= 线程安全吗?

我相信这个线程安全(记住 op= 的参数是按值传递的),而我能找到的唯一问题是隐藏在地毯下的问题:复制 ctor。但是,这将是一个罕见的类,它允许复制分配但不允许复制构造,因此该问题同样存在于两种替代方案中。

鉴于自我分配是如此罕见(至少对于这个例子来说),如果它发生我不介意额外的副本,考虑这个 != &rhs 的潜在优化可以忽略不计或悲观化。与原始策略(下)相比,是否还有其他理由更喜欢或避免它?


顺便说一句,我认为这简洁地处理了复制ctor,至少对于这个类,即使它有点迟钝:

0 投票
2 回答
34902 浏览

c++ - 公共朋友交换会员功能

copy-and-swap-idiom的漂亮答案中,有一段代码我需要一些帮助:

他加了一条注释

还有其他主张我们应该为我们的类型专门化 std::swap,提供类内交换以及自由函数交换等。但这都是不必要的:任何正确使用交换都将通过不合格的调用,我们的函数会通过ADL找到。一个功能就可以了。

friend必须承认,我有点“不友好”。所以,我的主要问题是:

  • 看起来像一个自由函数,但它在类体内?
  • 为什么这不是swap静态的?它显然不使用任何成员变量。
  • “任何正确使用交换都会通过 ADL 找到交换”?ADL 将搜索命名空间,对吗?但它是否也在类内部?还是从这里friend进来的?

附带问题:

  • 使用 C++11,我应该用 s 标记我swap的 snoexcept吗?
  • 使用 C++11 及其range-for,我应该在类friend iter begin()friend iter end()以相同的方式放置吗?我认为friend这里不需要,对吧?
0 投票
3 回答
2166 浏览

c++ - 安全分配和复制和交换习语

我正在学习 c++,我最近学习了(在堆栈溢出中)关于复制和交换习语的知识,我对此有一些疑问。因此,假设我有以下类使用复制和交换习语,例如:

我的问题是,假设我有另一个类,它有一个 Foo 对象作为数据但没有指针或其他可能需要自定义复制或分配的资源:

现在我有一系列问题:

  1. 上面为Bar类实现的方法和构造函数是否安全?使用了复制和交换来Foo确保在分配或复制时不会造成任何伤害Bar

  2. 在复制构造函数和交换中通过引用传递参数是强制性的吗?

  3. 是否可以说,当 的参数operator=按值传递时,为此参数调用复制构造函数以生成对象的临时副本,然后与该副本交换*this?如果我通过引用传递,operator=我会有一个大问题,对吧?

  4. 是否存在这种习语无法在复制和分配时提供完全安全的情况Foo

0 投票
4 回答
28669 浏览

c++ - 为什么有些人使用交换进行移动任务?

例如,stdlibc++ 有以下内容:

为什么不直接将两个 __u 成员分配给 *this 呢?交换是否暗示 __u 被分配了 *this 成员,只是后来分配了 0 和 false ......在这种情况下,交换正在做不必要的工作。我错过了什么?(unique_lock::swap 只是对每个成员执行 std::swap )

0 投票
3 回答
2080 浏览

c++ - 在可移动和不可复制的类上使用移动和交换习语是否有意义

如果我有一堂课,比如

如果我没有复制构造函数,按值实现 operator= 并交换是否有意义?它应该防止复制我的类对象,Foo但允许移动。

这个类是不可复制的,所以我不应该能够复制构造或复制分配它。

编辑

我已经用这个测试了我的代码,它似乎有我想要的行为。

0 投票
6 回答
793 浏览

c++ - 重用复制和交换习语

我正在尝试将复制和交换习语放入可重用的混合中:

我打算通过 CRTP 将其混合:

但是,一个简单的测试表明它不起作用:

这只会打印两次“default”,既不打印“copy”也不打印“swap”。我在这里想念什么?

0 投票
2 回答
914 浏览

c++ - 使用带有复制和交换的模板类未解决的外部问题

使用模板类时出现链接器错误,我尝试按照此处的建议实现复制和交换习惯用法:

什么是复制和交换成语?

模板类,我们称之为“TemplateClass”,部分定义如下:

我已将实现放在一个单独的 TemplateClass.cpp 中,该模板包含在 .h 文件中。(编辑:如果一切都在 .h 文件中,我有同样的问题)

赋值运算符定义为:

交换方法定义为:

(别担心,我并没有真正将我的成员命名为“member1”等)

我有一个类似的类,它以相同的方式定义,但不是模板类。那里一切正常。但是,如果我有一个TestClass有成员的类,TemplateClass< HandledClass > member并且我在它的一种方法中进行调用,例如

我得到一个未解决的外部错误:

LNK2019:函数“public: class TemplateClass X & __thiscall TemplateClass X::operator=(class TemplateClass)”(...) 中未解析的外部符号“void __cdecl swap(class TemplateClass &, class TemplateClass &)”(...)在 TestClass.obj 中

或者换句话说:TestClass调用TemplateClass<HandledClass>::operator=中找不到的东西void swap( TemplateClass<HandledClass>, TemplateClass<HandledClass> )

所以我的问题是:为什么运营商找不到swap方法?

看起来它不是为模板参数编译的。是否有可能让编译器也编译友元 voids?

我可能会放弃这种friend void方法并定义一个类内交换方法加上一个类外交换方法加上一个 std 命名空间中的一个,但我不知道它是否会这样工作,如果我想避免这种情况反正可能。


解决方案:

这完成了工作:

请注意我也必须删除 < T > 事件。

0 投票
1 回答
1416 浏览

visual-c++ - 如何交换 MFC CString?

好的,所以我对复制和交换习语很感兴趣,我想我主要知道如何实现它。

但是,或者代码库使用MFC 的 CString 类作为字符串,这不会改变。

既然swap必须(应该???)不是抛出,我不能

因为这将创建一个可能抛出的临时 CString 对象。(加上它的低效。)

那我还剩下哪里?我应该添加一个try-catch吗?我真的应该允许这种(嗯,非常罕见的)内存不足的情况引发异常并使交换失败吗?

查看 CStrings 实现,似乎没有允许交换的成员或函数......