【问题标题】:std::make_shared, std::unique_ptr and move constructorsstd::make_shared、std::unique_ptr 和移动构造函数
【发布时间】: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;
}

现在,问题:

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

编辑:经过检查,所有示例似乎都可以使用 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 最近实现了隐式移动。您可能必须使用显式删除的复制构造函数来禁用它才能触发症状。

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


【解决方案1】:

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

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

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

不,我不相信它可以。

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

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

更新

固定:http://llvm.org/bugs/show_bug.cgi?id=11616

【讨论】:

  • 哇!一小时转身!因此,如果我们在 clang/libc++ 中发现其他错误,我们可以将它们发布到 Stackoverflow 以羞辱您及时修复它们?
  • @deft_code :我认为霍华德足够正直,可以修复错误而不会因此而感到羞耻。 ;-]
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-01-20
  • 1970-01-01
  • 2014-05-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多