为了澄清:按值传递的答案没有错。string&&
但是,除了一个细节之外,您对添加重载的第一个猜测也不是:
添加:
X (std::string&& s) : S(std::move(s)) { }
也就是说,您仍然需要 ,move
因为尽管s
声明了 rvalue 引用的类型string
,但用于初始化的表达式 是 type 的左值表达式。s
S
string
实际上,您首先提出的解决方案(添加了移动)比传递值解决方案略快。但两者都是正确的。当将左值和 xvalue 参数传递给 X 的构造函数时,按值传递的解决方案会额外调用字符串的移动构造函数。
在左值参数的情况下,无论如何都会进行复制,并且字符串的复制构造函数可能比字符串的移动构造函数昂贵得多(除了适合短字符串缓冲区的字符串,在这种情况下移动和复制大致相同速度)。
对于 xvalue 参数(xvalue 是已传递给 的左值std::move
),按值传递解决方案需要两个移动构造而不是一个。因此它的成本是通过右值参考解决方案传递的两倍。但仍然非常快。
这篇文章的重点是要明确:按值传递是一种可接受的解决方案。但这不是唯一可接受的解决方案。使用 pass-by-rvalue-ref 进行重载更快,但缺点是随着参数数量 N 的增加,所需的重载数量会缩放为 2^N。