以下代码使用 clang 3.0/libc++ 编译:
#include <memory>
class Foo
{
public:
Foo()
: mem_(new int(10))
{
}
std::unique_ptr<int> mem_;
};
int main()
{
auto foo = std::make_shared<Foo>();
return 0;
}
但是这个没有(std::string
参数加了):
#include <memory>
#include <string>
class Foo
{
public:
Foo(const std::string& s)
: mem_(new int(10))
{
}
std::unique_ptr<int> mem_;
};
int main()
{
auto foo = std::make_shared<Foo>("aaa");
return 0;
}
Clang 提示使用了已删除的构造函数。对我来说,这没有任何意义,因为 std::make_shared
不应该复制 Foo 实例,这是唯一会触发对 std 的(已删除)复制构造函数的调用::unique_ptr
.
但是你瞧,只要我明确定义了移动构造函数,它就会编译。
#include <memory>
#include <string>
class Foo
{
public:
Foo(const std::string& s)
: mem_(new int(10))
{
}
Foo(Foo&& other)
: mem_(std::move(other.mem_))
{
}
std::unique_ptr<int> mem_;
};
int main()
{
auto foo = std::make_shared<Foo>("aaa");
return 0;
}
现在,问题:
- 为什么它在第一个示例中编译,而在第二个示例中不编译?
std::make_shared
可以在构造对象时复制/移动对象吗?- 为什么添加移动构造函数可以解决问题?我不记得添加非默认构造函数应该抑制隐式移动构造函数。
编辑:经过检查,所有示例似乎都可以使用 gcc 4.5.1(通过 ideone.com)编译,我怀疑这是 clang/libc++ 错误的情况,但问题 2 和 3 仍然存在立场,另外我想知道哪个编译器更“正确”。
最佳答案
Why does it compile in the first example but not the second?
这是一个 libc++ 错误。我现在正在修复它...
Can std::make_shared copy/move the object while constructing it?
不,我不相信它可以。
Why does adding a move constructor fix the problem? I don't recall that adding non-default constructor should suppress an implicit move constructor.
在您使用的 clang 版本中,尚未实现隐式移动构造函数。
更新
关于c++ - std::make_shared、std::unique_ptr 和移动构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8560994/