为啥 std::any 没有 unsafe_any_cast?

Posted

技术标签:

【中文标题】为啥 std::any 没有 unsafe_any_cast?【英文标题】:Why is there no unsafe_any_cast for std::any?为什么 std::any 没有 unsafe_any_cast? 【发布时间】:2018-01-17 13:32:03 【问题描述】:

我的本​​地版本的 Boost 标头 (1.56.0) 在 boost/any.hpp 中定义了以下函数,逐字复制:

// Note: The "unsafe" versions of any_cast are not part of the
// public interface and may be removed at any time. They are
// required where we know what type is stored in the any and can't
// use typeid() comparison, e.g., when our types may travel across
// different shared libraries.
template<typename ValueType>
inline ValueType * unsafe_any_cast(any * operand) BOOST_NOEXCEPT

    return &static_cast<any::holder<ValueType> *>(operand->content)->held;


template<typename ValueType>
inline const ValueType * unsafe_any_cast(const any * operand) BOOST_NOEXCEPT

    return unsafe_any_cast<ValueType>(const_cast<any *>(operand));

即使在线文档甚至不承认它们的存在:http://www.boost.org/doc/libs/1_59_0/doc/html/any/reference.html

我注意到std::any 似乎也不支持不安全的 any 演员表。

为什么C++17标准没有引入std::unsafe_any_cast

如果找不到确切的原因(或者如果根本没有提出),那么不提供对存储在 std::any 对象中的值的不安全访问的最有说服力的论点是什么?

【问题讨论】:

【参考方案1】:

std::any 是一个type-safe 容器,用于存放任何类型的单个值。

请注意,从您发布的 sn-p 中的评论中可以看出,Boost 的 unsafe_any_cast 不是公共界面的一部分。它是一个实现细节,并不打算由最终用户使用。这就是文档中没有提到它的原因。

将它提升到公共接口会破坏首先拥有类型安全容器的目的。

【讨论】:

我不同意最后一条语句,std::any 确实有用例,例如调用包含的对象构造函数或类型安全的复制。提供不安全的演员表不会破坏这些优势。 (unsafe_cast 的缺失是我仍然坚持使用 boost::any 的原因) @ViktorSehr 感谢您的评论。请注意,最后一段不是答案的重点。重点是 unsafe_any_cast 函数不是 Boost 的公共接口的一部分,这意味着它可能在未来的版本中不可用。最后一段从设计的角度添加了一个观点:拥有一个唯一目的是打破类的契约public函数并不是一个好的设计决策。如果您需要不安全的演员表,std::any(或boost::any,就此而言)可能不是要走的路。

以上是关于为啥 std::any 没有 unsafe_any_cast?的主要内容,如果未能解决你的问题,请参考以下文章

为啥在 dlopen'd 函数中传递的 std::any 的 std::any_cast 会引发错误

std::any 用于仅移动模板,其中 copy-ctor 内的 static_assert 等于编译错误,但为啥呢?

为啥 condition_variable_any 需要由 shared_ptr 管理的互斥锁?

有没有办法在不知道派生类型的情况下将包含派生指针的 std::any 转换为基指针?

std::any 由 std::exception_ptr

MSVC 2017 支持 std::any 吗?