【问题标题】:boost::signals::scoped_connection doesn't work in std::vector. why?boost::signals::scoped_connection 在 std::vector 中不起作用。为什么?
【发布时间】:2013-04-19 08:14:17
【问题描述】:

据我了解,scoped_connections 旨在在超出范围时自动断开连接,而不是之前。我发现当 scoped_connection 位于 std::vector 时,这无法正常工作(并且对于其他容器也可能失败)。

例如。

using boost::signals::scoped_connection; // just for readability
boost::signal<void ()> sig;
std::vector<scoped_connection> connection_vec;

connection_vec.push_back(sig.connect(foo));
assert(connection_vec.back().connected()); // this assertion fails!

我通过声称std::vector 要求元素是可复制的而scoped_connection 是不可复制的来解释这一点——但这并不完全正确。 std::vector 只要求元素是可移动的。 (我希望scoped_connection 应该是可移动的。)

例如,以下代码有效:

std::vector<std::unique_ptr<scoped_connection>> vec2;
// Note that std::unique_ptr is uncopyable, but moveable

vec2.push_back(std::unique_ptr<scoped_connection>(new scoped_connection(sig.connect(foo))));
assert((*vec2.back()).connected()); // this assertion succeeds!

此外,如果问题是由于std::vector 试图复制不可复制的东西,那么这不应该产生编译错误吗?

所以我想知道scoped_connectionvector 中无法正常工作的真正原因是什么,这是一个可以在 boost 中解决的问题吗?

(我在 gcc 版本 4.8.0 和 boost 版本 1.53.0 上对此进行了测试。)

【问题讨论】:

  • 这是 C++11 吗?或不?你将什么标志传递给gcc
  • 它是 C++11。 g++ -std=c++11 -Wall -DDEBUG -O0 -g

标签: c++ boost boost-signals


【解决方案1】:

scoped_connection 还没有移动构造函数。所以它不能像你想象的那样移动,而是std::move 将回退到复制。正如你提到的,你不能复制scoped_connection

【讨论】:

  • 你认为未来版本的 boost 应该包含一个用于 scoped_connection 的移动构造函数,并通过删除 copy_constructor 来严格执行禁止复制规则,你认为公平吗?
  • karadoc:是的,这是有道理的。您实际上可以自己做,并构建自己的 boost 版本。
  • Boost 1.56 以来已修复此问题(注意移动构造函数和移动赋值运算符)。
【解决方案2】:

您需要使用emplace_backpush_back 副本。

【讨论】:

  • 这并不能改变问题。由于emplace_back 会导致在重新分配内存时复制现有元素。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-08
  • 1970-01-01
相关资源
最近更新 更多