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

C++如何实现从任意容器推导其Wrapper包装后的对应容器类型

实现方案

可以通过模板特化 + C++17 auto非类型模板参数实现,完全满足所有要求,代码如下:

#include <type_traits>
#include <vector>
#include <map>
#include <array>

// 示例Wrapper模板
template<typename T>
struct Wrapper {};

// 主模板声明
template<template<typename> typename WrapT, typename ContainerT>
struct container_wrap;

// 特化1:匹配模板参数全为类型的容器(vector、map等)
template<template<typename...> typename ContainerTpl, template<typename> typename WrapT, typename... Ts>
struct container_wrap<WrapT, ContainerTpl<Ts...>> {
    using type = ContainerTpl<WrapT<Ts>...>;
};

// 特化2:匹配包含非类型模板参数的容器(std::array等)
template<template<typename, auto...> typename ContainerTpl, template<typename> typename WrapT, typename T, auto... NTParams>
struct container_wrap<WrapT, ContainerTpl<T, NTParams...>> {
    using type = ContainerTpl<WrapT<T>, NTParams...>;
};

// 对外接口,符合要求的调用语法
template<template<typename> typename WrapT, typename ContainerT>
using alias = typename container_wrap<WrapT, ContainerT>::type;

验证测试

通过静态断言验证匹配需求:

static_assert(std::is_same_v<alias<Wrapper, std::vector<int>>, std::vector<Wrapper<int>>>);
static_assert(std::is_same_v<alias<Wrapper, std::map<int, std::string>>, std::map<Wrapper<int>, Wrapper<std::string>>>);
static_assert(std::is_same_v<alias<Wrapper, std::array<int, 10>>, std::array<Wrapper<int>, 10>>);

实现说明

  • 解决调用语法问题:通过模板特化自动拆解传入的完整容器类型(如std::vector<int>),无需单独传入容器模板和元素参数,直接支持alias<Wrapper, 容器类型>的调用形式。
  • 解决std::array兼容问题:新增带非类型参数的特化分支,用auto... NTParams匹配并保留所有非类型模板参数,无需单独为std::array做分支区分。
  • 边界情况说明:对于带额外模板参数的标准容器(如std::map的比较器、分配器),上述实现会直接对所有类型参数做Wrapper转换。如果需要保留原容器的比较器、分配器逻辑,仅替换键值类型,可以针对标准容器单独补充特化分支。
  • 版本要求:该实现依赖C17引入的auto非类型模板参数特性,需要C17及以上编译版本。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 02:27:00