正确使用 const_cast 与第三方库

Posted

技术标签:

【中文标题】正确使用 const_cast 与第三方库【英文标题】:Using const_cast correctly with third party library 【发布时间】:2018-03-26 05:46:21 【问题描述】:

我有一个实现一些不可变数据结构的大型库。可以想象,其中几乎所有内容都是const 合格的。有一些选择部分不是 const,例如引用计数器。为了处理嵌入在通过const 方法和指针独占访问的结构中的引用计数器,使用了mutable 关键字。下面是Node 中的示例。这很好用,我对文档的阅读表明这很好。

我面临的问题是我还想使用 Boost.Intrusive 容器跟踪数据结构的某些部分,但这些容器没有 const 方法。

boost::intrusive::list my_bi_list; // as an example

struct Node 
  mutable boost::intrusive::list_member_hook<> bi_hook;
  mutable std::atomic<int> refcount;

  // const T a;
  // const T b;
  // ...

  inline void put() const 
    ...
    my_bi_list.push_back(*this); // PROBLEM here
  
;

在上面的Node 中,*this 用于将当前的Node 实例放在侵入列表中,但该接口采用非const 引用,导致您的标准C++ 限定符被丢弃错误。

我一直在阅读有关 const_cast(例如 push_back(const_cast&lt;Node&amp;&gt;(*this))的信息,但即使在阅读了我发现我正在冒险进入未定义的行为领域的文档之后,也不清楚。

这里的任何指导都将不胜感激(尤其是任何可以完全避免这种情况的技术!)

谢谢

【问题讨论】:

什么是my_bi_list 这是对 boost::intrusive::list 的引用 不允许const继承看起来像是标准中的一个漏洞...... 【参考方案1】:

使用boost::cref(x):

boost::cref(x) 返回一个 boost::reference_wrapper(x)

这样,您就可以使用 boost 的参考库并进行隐式转换。

【讨论】:

【参考方案2】:

您正在冒险进入未定义的行为领域。来自cppreference(备注下):

const_cast 使得可以形成指向实际引用 const 对象的非 const 类型的引用或指针,或者形成实际引用 volatile 对象的非易失类型的引用或指针。通过非 const 访问路径修改 const 对象并通过非易失性左值引用易失性对象会导致未定义的行为。

通常不能直接将 const 对象与侵入式容器结合使用。您可以做的是将要放入侵入式容器中的类型包装在您自己的非常量类型中。

【讨论】:

以上是关于正确使用 const_cast 与第三方库的主要内容,如果未能解决你的问题,请参考以下文章

使用 Qt 编译第三方库

强制 GCC 通知共享库中未定义的引用

让 QMake 生成正确的 .app

swift中第三方网络请求库Alamofire的安装与使用

使 Python 代码与第三方库可用于 unix 服务器

用 webpacker 导入第三方库最干净的方法是啥?