所以基本上我的问题是:什么时候应该使用右值引用?在本例中,我正在处理一个记录器类(它只是将事件记录到控制台...)。我有不同的功能来记录不同日志级别的消息。它们接受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);但是,让每个函数重复两次真的很奇怪,而且看起来也有点不必要……
发布于 2020-06-03 22:53:42
如果你要接受一个要复制并存储的字符串,最好不要引用:取值为。
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是一个模板参数。这实际上不是一个右值引用,而是一个所谓的转发引用,当你想根据模板上下文传递参数的右值时,它可以派上用场。
https://stackoverflow.com/questions/62175820
复制相似问题