我经常在生产代码中看到以下习惯用法:将值参数(如共享指针)传递给构造函数,并复制一次。为了确保这一点,参数包含在std::move
应用程序中。讨厌样板代码和形式噪音我想知道这是否真的有必要。如果我删除了应用程序,至少gcc 7会输出一些不同的程序集。
#include <memory>
class A
{
std::shared_ptr<int> p;
public:
A(std::shared_ptr<int> p) : p(std::move(p)) {} //here replace with p(p)
int get() { return *p; }
};
int f()
{
auto p = std::make_shared<int>(42);
A a(p);
return a.get();
}
Compiler Explorer向您展示了不同之处。虽然我不确定这里最有效的方法是什么,但我想知道是否存在允许将p
视为该特定位置的右值引用的优化?它当然是一个命名实体,但无论如何该实体在该位置之后“死”。
将“死”变量视为右值参考是否有效?如果没有,为什么?
答案 0 :(得分:2)
在构造函数的主体中,有两个p
个对象,ctor参数和this->p
。没有std::move
,它们是相同的。这当然意味着两个指针之间共享所有权。这必须以线程安全的方式实现,并且价格昂贵。
但要优化这一点非常困难。编译器通常不能推断出所有权是多余的。通过自己编写std::move
,您可以清楚地明确ctor参数p
不需要保留所有权。