是具有复制和交换习惯用法的复制赋值运算符,建议进行自赋值检查
Is copy assignment operator with copy and swap idiom and self assignment check recommended?
在这里,您可以看到带有自分配检查的复制分配运算符实现:
String & operator=(const String & s)
{
if (this != &s)
{
String(s).swap(*this); //Copy-constructor and non-throwing swap
}
// Old resources are released with the destruction of the temporary above
return *this;
}
这有利于自我分配,但对性能不利:
- 因为每次它都像语句一样检查(考虑到分支预测,我不知道它的最佳程度是多少)
- 我们这里也失去了右值参数的省略
所以我仍然不明白如果我要实现std::vector
的operator=
,我将如何实现它
是的,这段代码非常棒。的确,它正在造成额外的不必要的分支。有了适当的交换和移动语义,以下应该更具性能:
String& String::operator=(String s) { // note passing by value!
std::swap(s, *this); // expected to juggle couple of pointers, will do nothing for self-assingment
return *this;
}
还要注意的是,按价值接受论点更有益。
因为每次它都像语句一样检查(考虑到分支预测,我不知道它的最佳值是多少)
我认为你已经陷入了一个过早的优化圈。
检查自分配->如果代码写得正确,那么自分配是不必要的->如果你是认真的,为什么不显式地写swap
?->我们回到了的原点
现实地说,我只想实现Allocator,而不必担心它
此外,我们在这里失去了对右值参数的复制省略
我不这么认为。
#include <iostream>
#define loud(x) std::cout << x << "n";
struct foo
{
foo() { loud("default") }
~foo() { loud("destruct") }
foo(const foo&) { loud("copy") }
foo(foo&&) { loud("move") }
foo & operator=(const foo & s)
{
if (this != &s)
{
loud("copy assign")
}
return *this;
}
};
int main()
{
foo f;
foo g;
g = f;
}
输出:
default
default
copy assign
destruct
destruct
这是-fno-elide-constructors
。
您声称分支可能有问题,但-O2
的汇编输出向我表明,GCC甚至不发出operator=
的代码,只是直接输出"copy assign"
字符串。是的,我意识到我有一个简化的例子,但实际上是错误的起点。
相关文章:
- valgrind-hellgrind与泄漏检查的结果不同
- C++模板来检查友元函数的存在
- C++17复制构造函数,在std::unordereded_map上进行深度复制
- 在C++程序中输入的文本文件将不起作用,除非文本被复制和粘贴
- 检查输入是否不是整数或数字
- 使用strcpy将char数组的元素复制到另一个数组
- 是否可以初始化不可复制类型的成员变量(或基类)
- 试图让变量检查数组中的某些内容
- 为什么复制构造函数不需要检查输入对象是否指向自身?
- 如何检查文件复制和写入是否成功
- 如何检查文件是否复制成功?(便携式解决方案)C++
- 如何在块复制期间矢量化范围检查
- 类型 traits,用于检查参数包中的所有类型是否都是可复制构造的
- 是具有复制和交换习惯用法的复制赋值运算符,建议进行自赋值检查
- qt检查文件中是否存在文件,如果它没有提示用户输入其位置,则将文件复制到程序工作目录
- 检查类是否具有带TMP的复制构造函数
- 检查是否调用了复制构造函数
- 执行 SSE 内存复制导致的堆损坏 - CRT 检查找不到任何内容
- 检查类是否有复制函数?返回真或假
- c++有一种方法可以将优先级队列元素复制到vector中,这样就可以对其进行迭代以检查是否有重复项