std :: make_shared,std :: unique_ptr和移动构造函数

时间:2011-12-19 11:57:21

标签: c++ stl c++11 clang

以下代码使用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;
}

现在,问题:

  1. 为什么它在第一个例子中编译而不是在第二个例子中编译?
  2. 可以在构建对象时std::make_shared复制/移动对象吗?
  3. 为什么添加移动构造函数可以解决问题?我不记得添加非默认构造函数应该抑制隐式移动构造函数。
  4. 编辑:检查并且所有示例似乎都可以使用gcc 4.5.1编译(通过ideone.com),我怀疑这是clang / libc ++错误的情况,但问题2和3仍然存在我想知道哪个编译器更“正确”。

1 个答案:

答案 0 :(得分:20)

  

为什么它在第一个例子中编译而不在第二个例子中编译?

这是一个libc ++错误。我正在努力修复它......

  

std :: make_shared可以在构造对象时复制/移动对象吗?

不,我不相信它。

  

为什么添加移动构造函数可以解决问题?我不记得了   添加非默认构造函数应该抑制隐式移动   构造

在你正在使用的clang版本中,隐式移动构造函数尚未实现。

<强>更新

修正:http://llvm.org/bugs/show_bug.cgi?id=11616