std :: move in initializer lists

时间:2018-04-09 06:58:55

标签: c++ optimization reference

我经常在生产代码中看到以下习惯用法:将值参数(如共享指针)传递给构造函数,并复制一次。为了确保这一点,参数包含在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视为该特定位置的右值引用的优化?它当然是一个命名实体,但无论如何该实体在该位置之后“死”。

将“死”变量视为右值参考是否有效?如果没有,为什么?

1 个答案:

答案 0 :(得分:2)

在构造函数的主体中,有两个p个对象,ctor参数和this->p。没有std::move,它们是相同的。这当然意味着两个指针之间共享所有权。这必须以线程安全的方式实现,并且价格昂贵。

但要优化这一点非常困难。编译器通常不能推断出所有权是多余的。通过自己编写std::move,您可以清楚地明确ctor参数p不需要保留所有权。