我试图了解使用 WidgetURef::setName
(URef
是一个通用引用,由 Scott Meyers 创造的术语)与 的性能影响WidgedRRef::setName
(RRef
是一个 R 值引用):
#include <string>
class WidgetURef {
public:
template<typename T>
void setName(T&& newName)
{
name = std::move(newName);
}
private:
std::string name;
};
class WidgetRRef {
public:
void setName(std::string&& newName)
{
name = std::move(newName);
}
private:
std::string name;
};
int main() {
WidgetURef w_uref;
w_uref.setName("Adela Novak");
WidgetRRef w_rref;
w_rref.setName("Adela Novak");
}
我很欣赏对于通用引用应该使用 std::forward
来代替,但这只是一个(不完美的)示例来突出有趣的一点。
问题
在此特定示例中,使用一种实现与另一种实现相比对性能有何影响?虽然 WidgetURef
需要类型推导,但它在其他方面与 WidgetRRef
相同,不是吗?至少在这个特定的场景中,在这两种情况下参数都是一个 r-value
引用,所以不会创建临时对象。这个推理正确吗?
上下文
该示例取自 Scott Meyers 的“Effective Modern C++”(第 170 页)的 Item25。根据书上的说法(前提是我的理解是正确的!),采用通用引用的版本 T&&
不需要临时对象,而另一个版本采用 std::string&&
,确实如此。我真的不明白为什么。
最佳答案
setName(T&& newName)
with argument "Adela Novak"
得到 T duduced as const char (&)[12]
然后分配给 std::string
。
setName(std::string&& newName)
使用参数 "Adela Novak"
创建一个临时的 std::string
对象,然后移动分配给 std::string
。
第一个在这里效率更高,因为不涉及移动。
关于c++ - 性能比较:of(std::string&) vs f(T&&),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50581602/