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

如何基于std::make_from_tuple在堆上创建C++对象?

实现从元组创建堆对象并返回裸指针的C++函数

你可以基于C++17引入的std::apply来实现这个需求,它能帮你把元组的元素展开为构造函数的参数,同时支持完美转发,适配包括std::unique_ptr在内的各类需要移动语义的类型。

核心实现代码

#include <tuple>
#include <utility> // 用于std::forward和std::apply

template <typename T, typename Tuple>
T* make_new_from_tuple(Tuple&& tuple)
{
    return std::apply(
        [](auto&&... args) {
            return new T(std::forward<decltype(args)>(args)...);
        },
        std::forward<Tuple>(tuple)
    );
}

基础用法示例

用你给出的struct A来演示:

#include <string>

struct A
{
    int i_; double d_; std::string s_;

    A(int i, double d, const std::string& s) : i_(i), d_(d), s_(s) {}
};

int main()
{
    auto aTuple = std::make_tuple(1, 1.5, std::string("Hello"));
    A* aPtr = make_new_from_tuple<A>(aTuple);
    
    // 使用对象...
    delete aPtr; // 记得手动释放内存
    return 0;
}

支持移动语义的复杂场景

当元组包含std::unique_ptr这类需要移动的对象时,该实现也能正确处理:

#include <memory>

struct B
{
    std::unique_ptr<int> p_;
    B(std::unique_ptr<int> p) : p_(std::move(p)) {}
};

int main()
{
    auto bTuple = std::make_tuple(std::make_unique<int>(42));
    B* bPtr = make_new_from_tuple<B>(std::move(bTuple));
    
    // 使用对象...
    delete bPtr;
    return 0;
}

为什么这个方案更优

  • 避免了先通过std::make_unique创建智能指针再调用release()的冗余操作,直接裸指针构造更高效直观。
  • 依赖std::apply的完美转发特性,确保元组中元素的值类别(左值/右值)被正确传递给构造函数,适配各类构造场景。
  • 与std::make_from_tuple的C版本要求一致(C17及以上),无需额外依赖。

内容的提问来源于stack exchange,提问作者CashCow

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 04:35:27