【发布时间】:2011-12-19 11:57:21
【问题描述】:
以下代码使用 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 仍然存在立场,另外我想知道哪个编译器更“正确”。
【问题讨论】:
-
我认为从来没有提供过隐式移动构造函数
-
@parapura rajkumar (1) 移除 unique_ptr 使其消失(即使使用非默认 ctor),(2) 仍根据最新措辞定义隐式移动构造函数:mmocny.wordpress.com/2010/12/09/implicit-move-wont-go跨度>
-
@parapurarajkumar:确实,我记得读过讨论,其中隐式移动构造函数是一件坏事,应该从标准中删除。但是,我不知道故事的结局。
-
new int(10)不分配十个整数,只分配一个并将其初始化为 10。也许你想要new int[10]? -
@Cubbi:clang 最近实现了隐式移动。您可能必须使用显式删除的复制构造函数来禁用它才能触发症状。