Should I always move on `sink` constructor or setter arguments?(我应该总是继续使用 `sink` 构造函数或 setter 参数吗?)
问题描述
struct TestConstRef {
std::string str;
Test(const std::string& mStr) : str{mStr} { }
};
struct TestMove {
std::string str;
Test(std::string mStr) : str{std::move(mStr)} { }
};
在观看 GoingNative 2013 后,我明白 sink 参数应该始终按值传递并使用 std::move
移动.TestMove::ctor
是应用这个习语的正确方法吗?是否存在 TestConstRef::ctor
更好/更高效的情况?
After watching GoingNative 2013, I understood that sink arguments should always be passed by value and moved with std::move
. Is TestMove::ctor
the correct way of applying this idiom? Is there any case where TestConstRef::ctor
is better/more efficient?
琐碎的 setter 呢?我应该使用以下习语还是传递 const std::string&
?
What about trivial setters? Should I use the following idiom or pass a const std::string&
?
struct TestSetter {
std::string str;
void setStr(std::string mStr) { str = std::move(str); }
};
推荐答案
简单的答案是:是的.
原因也很简单,如果您按值存储,您可能需要移动(从临时)或复制(从左值).让我们看看在这两种情况下会发生什么,两种方式.
The reason is quite simple as well, if you store by value you might either need to move (from a temporary) or make a copy (from a l-value). Let us examine what happens in both situations, with both ways.
来自临时
- 如果您通过 const-ref 获取参数,则临时对象将绑定到 const-ref 并且无法再次移动,因此您最终会制作一个(无用的)副本.
- 如果您按值获取参数,则该值将从临时(移动)中初始化,然后您自己从该参数中移动,因此不会进行复制.
一个限制:一个没有高效移动构造函数的类(例如 std::array
),因为那样你做了两个副本而不是一个.
One limitation: a class without an efficient move-constructor (such as std::array<T, N>
) because then you did two copies instead of one.
从左值(或 const 临时,但谁会这样做...)
From a l-value (or const temporary, but who would do that...)
- 如果你通过 const-ref 获取参数,那里什么都不会发生,然后你复制它(不能从中移动),这样就得到了一个副本.
- 如果您按值获取参数,则将其复制到参数中,然后从参数中移出,从而生成单个副本.
一个限制:相同的...类,移动类似于复制.
One limitation: the same... classes for which moving is akin to copying.
因此,简单的答案是,在大多数情况下,通过使用接收器,您可以避免不必要的副本(通过移动来替换它们).
So, the simple answer is that in most cases, by using a sink you avoid unnecessary copies (replacing them by moves).
唯一的限制是移动构造函数与复制构造函数一样昂贵(或接近一样昂贵)的类;在这种情况下,有两个动作而不是一个副本是最糟糕的".幸运的是,这样的类很少见(数组是一种情况).
The single limitation is classes for which the move constructor is as expensive (or near as expensive) as the copy constructor; in which case having two moves instead of one copy is "worst". Thankfully, such classes are rare (arrays are one case).
这篇关于我应该总是继续使用 `sink` 构造函数或 setter 参数吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:我应该总是继续使用 `sink` 构造函数或 setter 参数吗?


基础教程推荐
- 在 C++ 中循环遍历所有 Lua 全局变量 2021-01-01
- 如何“在 Finder 中显示"或“在资源管理器中显 2021-01-01
- Windows Media Foundation 录制音频 2021-01-01
- 使用从字符串中提取的参数调用函数 2022-01-01
- 如何在不破坏 vtbl 的情况下做相当于 memset(this, ...) 的操作? 2022-01-01
- 为 C/C++ 中的项目的 makefile 生成依赖项 2022-01-01
- 从 std::cin 读取密码 2021-01-01
- 如何使图像调整大小以在 Qt 中缩放? 2021-01-01
- 管理共享内存应该分配多少内存?(助推) 2022-12-07
- 为什么语句不能出现在命名空间范围内? 2021-01-01