【问题标题】:initialization with `auto` needs copy constructor? [duplicate]使用“auto”进行初始化需要复制构造函数吗? [复制]
【发布时间】:2015-02-17 16:23:37
【问题描述】:

下面的初始化,

auto p = std::make_pair(std::stringstream{}, "Hello World!");

使用libc++ 编译并与clang++ 正常工作。

但是,使用 libstdc++ 编译它时,clang++g++ 都会出错,

error: use of deleted function 'std::basic_stringstream<char>::basic_stringstream(const std::basic_stringstream<char>&)'

来自g++,并且

error: call to implicitly-deleted copy constructor of 'std::basic_stringstream<char>'

来自clang++,使用libstdc++

我对标准的理解是,这种类型的声明加初始化不应该涉及拷贝构造函数。我错了吗? libc++ 应该允许这种初始化吗?还是libstdc++不正确?

编辑:在您回复后,我知道这是 gcc 中的一个错误,直到 v5 才会修复。无论是使用复制初始化还是直接初始化,调用make_pair 总是需要移动或复制构造函数,这在当前有缺陷的 gcc 下会出错。所以我的问题是如何轻松地重写我的代码来规避这个错误。我有一个类层次结构,它有一个stringstream 类型的成员。删除它会导致太多的头痛。使用unique_ptr 是唯一的方法吗?

【问题讨论】:

  • 可能libstdc++没有更新到c++11
  • @Cheersandhth.-Alf 看起来像gcc bug 54316,应该在 gcc 5 (o.O) 中修复
  • @Cheersandhth.-Alf:libstdc++ 在很长一段时间内(大约八年)中有 lot 的 C++11。但是还是有几个坑。您不会一次性获得整个新标准。

标签: c++ c++11 copy-constructor auto


【解决方案1】:

即复制初始化,必须有一个可访问的构造函数来将转换后的值传输到新对象中。

但是,应该选择移动构造函数。 (假设您的 libstdc++ 副本足够新,可以为 std::pair 提供一份)

无论如何,最好使用直接初始化:

auto p(std::make_pair(std::stringstream{}, "Hello World!"));

【讨论】:

  • @dyp:我不明白你的问题?从 C++11 开始,复制初始化可以选择移动构造函数。
  • @dyp: 哦,该死的,你是对的。切换到()
  • 您已经知道这一点,但对每个人来说可能并不明显:在这种情况下,直接初始化也需要一个复制/移动构造函数,并且在这里与复制初始化具有相同的语义。 (它只允许使用显式的ctors。)
  • g++ / libstdc++ 在直接初始化时仍然给出同样的错误。
猜你喜欢
  • 2020-05-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-04
  • 2011-09-10
  • 2023-03-05
相关资源
最近更新 更多