c++ - std::make_shared、std::unique_ptr 和移动构造函数

标签 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. 为什么添加移动构造函数可以解决问题?我不记得添加非默认构造函数应该抑制隐式移动构造函数。

编辑:经过检查,所有示例似乎都可以使用 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 版本中,尚未实现隐式移动构造函数。

更新

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

关于c++ - std::make_shared、std::unique_ptr 和移动构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8560994/

相关文章:

c++ - 泄漏 sanitizer 检测泄漏

c++ - boost asio 绑定(bind) : bad file descriptor

c++ - std::greater 未在 MSVC2012 中定义

c++ - 有效地填补有序数字列表中的第一个空白

c++ - 如何在窗口中显示文件夹中所有文件的名称? Qt C++

c++ - 存储在 std::function 中时,无捕获 lambda 无法转换为函数指针

c++ - 通过 UDP 套接字发送结构 memcopy C++

c++ - 如何使假定派生类变量的相邻存储的黑客合法化?

c++ - 如果一个线程正在执行的仿函数被移动会发生什么?

c++ - 在什么情况下 C++ 会在编译时进行数组边界检查?