正确使用 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<Node&>(*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 与第三方库的主要内容,如果未能解决你的问题,请参考以下文章