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

Ale*_*x B 12 c++ stl clang c++11

以下代码使用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;
}
Run Code Online (Sandbox Code Playgroud)

但是这个没有(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;
}
Run Code Online (Sandbox Code Playgroud)

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;
}
Run Code Online (Sandbox Code Playgroud)

现在,问题:

  1. 为什么它在第一个例子中编译但不在第二个例子中编译?
  2. 可以std::make_shared在构建对象时复制/移动对象吗?
  3. 为什么添加移动构造函数可以解决问题?我不记得添加非默认构造函数应该抑制隐式移动构造函数.

编辑:检查和所有示例似乎编译与gcc 4.5.1(通过ideone.com),我怀疑这是一个clang/libc ++错误的情况,但问题2和3仍然有效,另外我想知道哪个编译器更"正确".

How*_*ant 20

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

这是一个libc ++ bug.我现在正在修复它...

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

不,我不相信它可以.

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

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

更新

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

  • 哇!转一个小时!因此,如果我们在clang/libc ++中发现其他错误,我们可以将它们发布到Stackoverflow以羞辱您及时修复它们吗? (5认同)
  • @deft_code:我认为霍华德的表现足以修复错误而不会被羞辱.; - ] (3认同)
  • @deft_code:这似乎是一种效果技巧.;-) (3认同)