c++ - 何时使用右值引用
问题描述
所以基本上我的问题是:我什么时候应该使用右值引用?在这个例子中,我正在研究一个记录器类(它只是将事情记录到控制台......)。我有不同的功能来记录不同日志级别的消息。他们接受一个 std::string 作为参数。我是否应该有每个函数的两个版本,第一个用于“正常”引用,第二个用于右值引用?
namespace lnr
{
class logger
{
public:
logger(const string& name);
logger(const string&& name);
~logger() = default;
const void trace(const string& message) const;
const void trace(const string&& message) const;
const void info(const string& message) const;
const void info(const string&& message) const;
const void warn(const string& message) const;
const void warn(const string&& message) const;
const void error(const string& message) const;
const void error(const string&& message) const;
private:
const string name;
};
}
因为两者都记录一些东西是很常见的
logger.trace("Hello");
和
std::string error_message = "...";
logger.error(error_message);
但是每个函数都有两次真的很奇怪,而且似乎也有点不必要......
解决方案
如果您要接收要复制和存储的字符串,则最好根本不使用引用:取值。
struct T
{
T(std::string str) : m_str(std::move(str)) {}
private:
std::string m_str;
};
现在,制作T
(哈哈!)的人可以只传递一个现有的字符串,该字符串将被复制而不影响原始字符串……或者他们可以std::move
是一个他们不再需要的字符串。
因此,如果您需要一份副本,您只需获得一份;如果你不这样做,你只会得到一连串的动作。又好又便宜!
如果您接收一个字符串只是为了在该函数中使用,即您没有取得所有权,那么没有理由为此烦恼。只接受一个漂亮的老式const std::string&
.
void foo(const std::string& str)
{
std::cout << str << '\n';
}
虽然有一些罕见的例外,但我通常只有一个函数在它是移动构造函数或移动赋值运算符时才采用右值引用。我们这样做是因为语言的“重载解决”规则的语义是围绕以这种方式工作的移动构建的(并且因为像我的第一个示例一样,当我们没有“目标”对象放入时,不希望有一个可能的副本)。
您还将看到类似auto&&
, 或模板参数T&&
在哪里的内容。T
这实际上不是一个右值引用,而是一个所谓的转发引用,当你想尽可能地传递一个参数的右值性时,它可以使用,具体取决于模板上下文。
推荐阅读
- algorithm - 递归地将数字 4 的所有分区枚举为四个有序数字?
- java - Java 中的 Azure 函数在本地无法运行
- laravel - Laravel 7 - 随机延迟(主要是 ajax 请求 - 从 300ms 到随机 4,5s)
- ios - 在 ViewWillAppear 和 ViewWillDisappear UI 故障处隐藏/显示导航栏
- php - Laravel/homestead - 没有指定输入文件
- javascript - 将组件道具传递到 ReactJS/NextJS 中的字符串中
- ios - ModelPresentationStyle FullScreen 总是隐藏状态栏
- javascript - *this* 对象在 React 组件中是“未定义的”
- python - 通过sftp成功上传后删除本地机器中的文件
- javascript - React:番茄钟:考虑到状态的异步更新,如何正确更新状态?