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

C++模板匹配容器与内容:适配单层及多层嵌套容器的实现

解决方案

一、基础版:支持Test<std::vector<int>>用法

要实现直接传入实例化后的容器类型,我们可以通过模板偏特化拆解容器的类型参数,步骤如下:

  1. 先声明空的主模板,留待特化实现:
template <typename T>
class Test;
  1. 编写针对单参数容器实例的偏特化版本:
template <template <typename> typename Container, typename Content>
class Test<Container<Content>> final
{
public:
    Container<Content> m;
    // 定义类型别名,方便外部直接访问容器和内容类型
    using container_type = Container<Content>;
    using value_type = Content;
};

此时即可直接使用Test<std::vector<int>> test;,编译器会自动匹配偏特化模板,拆解出Container为std::vector、Content为int。

如果需要兼容原有的Test<std::vector, int>用法,只需添加另一套偏特化:

// 保留原有用法的偏特化版本
template <template <typename> typename Container, typename Content>
class Test<Container, Content> final
{
public:
    Container<Content> m;
    using container_type = Container<Content>;
    using value_type = Content;
};

二、进阶版:处理多层嵌套的容器/视图类型

对于std::ranges::filter_view<std::ranges::ref_view<std::vector<int>>>这类多层嵌套的视图,我们需要递归类型萃取穿透外层封装,提取最底层的内容类型和原始容器。

1. 实现递归类型萃取器

定义一个工具模板,递归适配不同类型的视图与容器:

#include <type_traits>
#include <ranges>

// 基础情况:直接获取类型的value_type
template <typename T>
struct value_type_trait {
    using type = typename T::value_type;
    using container_type = T;
};

// 递归处理带有inner_range_type的视图(如filter_view、transform_view)
template <typename T>
requires requires { typename T::inner_range_type; }
struct value_type_trait<T> {
    using inner_trait = value_type_trait<typename T::inner_range_type>;
    using type = typename inner_trait::type;
    using container_type = typename inner_trait::container_type;
};

// 单独处理ref_view:直接指向底层容器
template <typename T>
struct value_type_trait<std::ranges::ref_view<T>> {
    using type = typename T::value_type;
    using container_type = T;
};

// 处理带有base_type的视图(部分range适配器)
template <typename T>
requires requires { typename T::base_type; }
struct value_type_trait<T> {
    using inner_trait = value_type_trait<typename T::base_type>;
    using type = typename inner_trait::type;
    using container_type = typename inner_trait::container_type;
};

// 定义别名简化使用
template <typename T>
using value_type_t = typename value_type_trait<T>::type;

template <typename T>
using underlying_container_t = typename value_type_trait<T>::container_type;

2. 修改Test类适配嵌套类型

调整Test类的主模板与偏特化,利用萃取器处理任意嵌套类型:

// 主模板声明
template <typename T, typename = void>
class Test;

// 特化1:兼容原有Test<Container, Content>用法
template <template <typename> typename Container, typename Content>
class Test<Container, Content> final
{
public:
    Container<Content> m;
    using container_type = Container<Content>;
    using value_type = Content;
};

// 特化2:支持传入任意容器/视图类型(含多层嵌套)
template <typename ContainerInstance>
class Test<ContainerInstance, std::void_t<value_type_t<ContainerInstance>>> final
{
public:
    ContainerInstance m;
    using container_type = ContainerInstance;          // 外层完整视图/容器类型
    using value_type = value_type_t<ContainerInstance>; // 最底层内容类型
    using underlying_container_type = underlying_container_t<ContainerInstance>; // 最底层原始容器类型
};

用法示例

#include <vector>
#include <ranges>

int main() {
    // 原有用法依然有效
    Test<std::vector, int> test1;

    // 新用法:直接传入实例化容器
    Test<std::vector<int>> test2;

    // 嵌套视图用法
    std::vector<int> vec = {1,2,3,4};
    auto filtered = vec | std::views::filter([](int x){return x%2==0;});
    Test<decltype(filtered)> test3;

    // 此时test3.value_type为int,test3.underlying_container_type为std::vector<int>
    return 0;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 12:27:03