【问题标题】:Error: "cannot access private member declared in class 'boost::signals2::scoped_connection'"?错误:“无法访问在类 'boost::signals2::scoped_connection' 中声明的私有成员”?
【发布时间】:2012-05-13 13:47:13
【问题描述】:
class Whatever
{
public:
    virtual ~Whatever();

protected:
    Whatever();
    virtual void SomeMethod();
    void OnEventOccurred(int x);

    std::vector<boost::signals2::scoped_connection> boostSignalConnections_;
}

// .cpp

Whatever::SomeMethod()
{
    ...
    boostSignalConnections_.push_back(
        anObject->AddEventOccurredObserver(
            std::bind(&Whatever::OnEventOccurred,
                      this, std::placeholders::_1)));
    ...
}

(注意AddEventOccurredObserver 只是委托给boost::signals2::connect() 并返回boost::signals2::connection

我收到以下错误。很难解释模板错误,但似乎是std::vector&lt;boost::signals2::scoped_connection&gt; boostSignalConnections_;的成员声明引起的错误

...\vc\include\xmemory(202): error C2248:  
    'boost::signals2::scoped_connection::scoped_connection' :
    cannot access private member declared in class 'boost::signals2::scoped_connection'
...\boost_1_47\boost\signals2\connection.hpp(234) : see declaration of
'boost::signals2::scoped_connection::scoped_connection'
...\boost_1_47\boost\signals2\connection.hpp(210) :
    see declaration of 'boost::signals2::scoped_connection'
...\vc\include\xmemory(201) : while compiling class template member function
'void std::allocator<_Ty>::construct(boost::signals2::scoped_connection *,_Ty &&)'
with
[
    _Ty=boost::signals2::scoped_connection
]

我已经搜索过,我认为这可能与 scoped_connection 不可复制有关?我不知道。我使用 scoped_connection 的原因是因为这个 SO 问题: Handle connection/disconnection of many signals/slots with boost::signals2

更新

仅供参考,当我从 scoped_connection 更改为 connection 时,它可以工作:std::vector&lt;boost::signals2::connection&gt; boostSignalConnections_;。我使用scoped_connection 的全部原因是它们会在破坏时自动断开连接,而我相信connection 不会。但是,我可以遍历集合并手动断开每个集合。

【问题讨论】:

  • 你说得对,问题在于复制构造函数是私有的。由于vector 需要在重新分配的情况下复制元素(例如由于扩展),所以这是一个问题。不过,我没有最适合您的解决方案,所以我将把它留给其他人来实际回答“我应该怎么做?”这个隐含的问题。我的第一个天真的反应是保留一个指向堆分配连接的指针/引用向量,但这显然几乎消除了等式中scoped 部分的用处。

标签: c++ boost boost-signals noncopyable boost-signals2


【解决方案1】:

boost::signals2::scoped_connection 是不可复制的,而在 C++03 中,std::vector&lt;T&gt; 要求 T 既可复制构造又可复制分配(此要求在 C++11 中放宽,其中不可复制的可复制类型是可以的,只要它是可移动的)。

天真的解决方案是将boostSignalConnections_ 改为std::vector&lt;scoped_connection*&gt;,但这会引入不值得努力的对象生命周期和异常安全问题。相反,根据您的编译器的最新程度,我会推荐以下内容:

  • C++03:使用boost::ptr_vector&lt;scoped_connection&gt;,它将为您存储指针(允许不可复制的类型)但为您提供值语义,并消除上述对象生命周期和异常安全问题。
  • C++11:以上仍然是一个有效的选项,但更惯用的方法是使用std::vector&lt;std::unique_ptr&lt;scoped_connection&gt;&gt;

话虽如此,如果您不希望对象具有词法范围,为什么要使用 scoped_connection

【讨论】:

  • 好问题,但正如我所提到的,我正在按照我的问题中链接到的问题中的示例进行操作(尽管它使用地图,所以它可能不同?)使用范围对象对我来说似乎不寻常在容器中,但我对它们不太熟悉。
  • @User : 对,关联容器值的要求比序列容器值和关联容器键的要求低。
  • @ildjarn 当您说boost::ptr_vector&lt;&gt; 维护对象生命周期时,是否意味着它正在后端部署 smart_pointers 以实现相同的目标?如果有,是哪一个?
  • @CinCout :我没有看过实现,但 AFAIK 是一个非公开的实现细节;很可能在图书馆的环境之外它不会有用。最好将boost::ptr_vector&lt;&gt; 视为不需要智能指针的“智能容器”。 ;-]
  • @ildjarn 所以保证内存管理是由容器来处理的?还是有任何(额外的)普通例外?
猜你喜欢
  • 1970-01-01
  • 2014-01-10
  • 1970-01-01
  • 1970-01-01
  • 2016-12-02
  • 1970-01-01
相关资源
最近更新 更多