You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

能否避免boost::type_erasure::any移动时的内存分配?

Boost.TypeErasure any移动构造时的内存分配能否避免?

在以下测试用例中,移动boost::type_erasure::any对象时会触发动态内存分配:

#include <boost/type_erasure/any.hpp>

#include <string>

int main() {
    typedef ::boost::mpl::vector<
        boost::type_erasure::destructible<>,
        boost::type_erasure::constructible<boost::type_erasure::_self(
            boost::type_erasure::_self&&)> >
        my_concept;
    typedef boost::type_erasure::any<my_concept> my_any;

    my_any a1(std::string("Test"));
    my_any a2 = std::move(a1); // 此处触发动态内存分配
}

这段代码中,a2的移动构造会调用boost/type_erasure/constructible.hpp中的逻辑分配内存:

template<class R, class... T>
struct constructible<R(T...)>
{
    static ::boost::type_erasure::detail::storage
    apply(T... arg)
    {
        ::boost::type_erasure::detail::storage result;
        result.data = new R(::std::forward<T>(arg)...);
        return result;
    }
};

原本期望通过移动语义直接接管原对象的存储以避免new操作,但调试和基准测试都确认了内存分配的存在,且未找到对应的内置concept优化该场景。


可以避免,但需要自定义扩展boost::type_erasure的concept和实现,默认的constructible仅负责构造新对象,不会处理any内部存储的转移。具体实现步骤如下:

  1. 定义自定义转移所有权的concept
    创建一个名为transferable的concept,用于描述直接转移内部存储的操作:

    struct transferable : ::boost::type_erasure::concept_interface<
        transferable,
        ::boost::mpl::vector<>>
    {
        virtual void transfer(::boost::type_erasure::detail::storage& target) = 0;
    };
    
  2. 为类型包装器实现该concept
    针对any内部的类型包装器,实现transfer方法,直接转移存储指针并清空原存储:

    template<class T, class Base>
    struct transferable_impl : Base
    {
        void transfer(::boost::type_erasure::detail::storage& target) override
        {
            target.data = this->data;
            this->data = nullptr;
        }
    };
    
  3. 更新concept集合
    修改你的my_concept,加入自定义的transferable:

    typedef ::boost::mpl::vector<
        boost::type_erasure::destructible<>,
        transferable>
        my_concept;
    
  4. 自定义any的移动构造函数
    手动调用transfer方法转移存储,替代默认的constructible逻辑:

    my_any::my_any(my_any&& other)
    {
        ::boost::type_erasure::call(transferable(), other, this->storage_);
        other.storage_.data = nullptr; // 清空原对象存储,避免重复析构
    }
    

另外,也可以利用boost::type_erasure::any的rebind机制或直接操作内部storage接口来管理所有权转移,但上述自定义concept的方式更贴合库的设计模式。

需要注意:所有被any包装的类型,在存储转移后原对象必须处于可安全析构的状态(符合移动语义的要求),否则会引发未定义行为。


内容的提问来源于stack exchange,提问作者Stefan v.K.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 09:20:09