以下代码可以使用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仍然存在,另外我想知道哪个编译器更加“正确”。