shared_ptr 构造函数参数是否应该按值传递

Should shared_ptr constructor arguments be passed by value

当我将 shared_ptr 传递给将参数复制到成员 shared_ptr 的构造函数时,是否应该按值传递此参数?

示例:

struct MyClass {
    MyClass(std::shared_ptr<MyDependency> dep) 
        : dep(dep)
    {}

    std::shared_ptr<MyDependency> dep;
};

如果使用临时 (MyClass(std::make_shared<...>())) 构建,编译器应该移动参数(一次或两次?)。

编译器是否能够"auto"将dep移动到dep, 或者我应该使用 : dep(std::move(dep))?

如果用左值构造,值将被复制(最少一次)。

另一方面,通过 const-ref 传递 shared_ptr 将始终复制指针。

那么如果构造函数参数将被直接复制到一个成员中,那么它们应该按值传递吗?

编辑: parameter/member 必须是 shared_ptr

Should shared_ptr constructor arguments be passed by value

如果您打算共享所有权,即您想要保留副本:是的,按值传递是首选方式。

If constructed with a temporary ... the compiler should move the argument (once or twice?).

首先对参数进行移动构造,然后对成员进行初始化(见下文)。在某些情况下,参数的构造可能会被省略。

should I use : dep(std::move(dep))

是的,你应该。参数有一个名字,所以它是一个左值。要移动构造成员,您需要有一个右值。

我个人的方法是使用两个构造函数:

struct MyClass
{
    MyClass(std::shared_ptr<MyDependency> const& dep) 
        : dep(dep)
    {}
    MyClass(std::shared_ptr<MyDependency>&& dep) 
        : dep(std::move(dep))
    {}

    std::shared_ptr<MyDependency> dep;
};

传递的 L 值,外部指针保留所有权,只像往常一样复制一次,r 值仍然只是引用,因此只移动一次。