乍一看,您似乎可以这样做:
A (std::unique_ptr<int> data = {new int(10)})
: mData(std::move(data))
{}
请注意花括号的使用(即统一初始化)。但是,这不起作用(无法编译),因为unique_ptr
接受指针的构造函数被声明为explicit
,这在此处排除了它的使用。
你可以做的另一件事是:
A (int * data = new int(10))
: mData (data)
{}
也就是说,接受一个普通的指针并从中构造你的成员。而且你也不需要离开它(std::move
尽管仍然推荐。)
这个确实可以编译并且可以工作,但是它有一个致命的缺陷,即尽管您正在接管传入指针的所有权(您将要访问delete
它),但您并没有在界面中显示此行为。因此,这个新界面将比以前的界面提供更少的信息。
另一种方法是编写一个快捷函数模板,如下所示:
template <typename T>
std::unique_ptr<T> uptr (T * v)
{
return std::unique_ptr<T>(v);
}
然后,您的构造函数变为:
A(std::unique_ptr<int> data = uptr(new int(10)))
: mData(std::move(data))
{}
但在我看来,这并没有太大的进步。
但是,如果这个特定用例是您的全部问题,为什么不直接定义一个默认构造函数和一个单参数构造函数,如下所示:
A ()
: mData (new int (10))
{}
/*explicit*/ A (std::unique_ptr<int> data)
: mData(std::move(data))
{}
这只是更明智。(请注意,提出explicit
一个好主意和好形式,但与您的问题无关,因此我已将其注释掉。)
此外,您的第二个构造函数实际上并没有移动任何东西。在这种情况下,r 值引用类型不像您认为的那样工作。简而言之,既然data
有了名字,它就不再是一个右值,尽管它的类型仍然是对某物的右值引用。