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

基于条件从元组生成引用元组的C++实现方案

C++模板容器筛选问题

问题背景

我定义了如下模板结构:

  • ContainerInner:内含存储可变模板类型vector的元组m_elements,提供contains静态方法判断是否包含指定类型,以及get方法获取对应vector的引用。
  • Container:内含ContainerInner类型的元组m_containers,当前getTuples方法返回所有ContainerInner的引用元组。
template<typename... Args>
struct ContainerInner
{
    std::tuple<std::vector<Args>...> m_elements;

    template<typename T>
    static constexpr bool containsOne()
    {
        return (std::is_same_v<T, Args> || ...);
    }

    template<typename... T>
    static constexpr bool contains()
    {
        return (containsOne<T>() && ...);
    }

    template<typename T>
    std::vector<T> &get()
    {
        return std::get<std::vector<T>>(m_elements);
    }
};

template<typename... T>
struct ArgList {
    template<typename... TTS>
    using add = ArgList<T..., ContainerInner<TTS...>>;
};
    
template<typename ListArgs>
struct Container;

template<typename... Args>
struct Container<ArgList<Args...>>
{
    std::tuple<Args...> m_containers;

    // 改成std::tuple<Args&...>返回类型也会崩溃
    template<typename... T>
    inline auto getTuples()
    {
        auto tpl = std::make_tuple<Args&...>(std::get<Args>(m_containers)...);
        return tpl;
    }

    template<typename... T>
    ContainerInner<T...> &get()
    {
        return std::get<ContainerInner<T...>>(m_containers);
    }
};

using MyArgList = ArgList<>
    ::add<char, int>
    ::add<char, float>
    ::add<char, int, float>;

int main(int argc, char* args[])
{    
    Container <MyArgList> cnt;

    auto arr = cnt.getTuples<float>();

    std::get<ContainedType<char, int>>(arr).get<int>().push_back(3);

    std::cout << typeid(arr).name() << std::endl;
    std::cout << cnt.get<char, int>().get<int>().size() << std::endl;
}

需求

修改getTuples方法,使其返回m_containers中所有包含指定类型的ContainerInner的引用元组,判断条件由contains静态方法处理。我尝试用如下concept实现:

template<typename InnerCnt, typename T>
concept ContainedType = 
    requires(T a, InnerCnt b) {
       b.contains<T>();
    };

但找不到递归遍历可变模板并通过std::tuple_cat构建结果的方法,该如何解决?

已实现方案及疑问

我通过封装Query结构体(重载operator+)实现了功能,但不确定编译器优化效果,担心运行时会生成临时Query对象:

template<typename... Args>
struct Query
{
    std::tuple<Args...> m_tpl;

    template<typename... TT>
    constexpr inline auto operator+(const Query<TT...> &rhs_)
    {
        return Query<Args..., TT...>(std::tuple_cat(m_tpl, rhs_.m_tpl));
    }

    template<typename... TT>
    constexpr inline auto &get()
    {
        return std::get<ContainerInner<TT...>&>(m_tpl);
    }
};

template<typename LST, typename CONTAINER_INNER>
constexpr inline auto getQueryElem(CONTAINER_INNER &t_)
{
    return Query<>();
}

template<typename LST, typename CONTAINER_INNER> requires Contained<CONTAINER_INNER, LST>
constexpr inline auto getQueryElem(CONTAINER_INNER &t_)
{
    return Query(std::tuple<CONTAINER_INNER&>(t_));
}


// 放在Container内部的getTuples方法
template<typename... T>
constexpr inline auto getTuples()
{
    return (getQueryElem<Typelist<T...>>(std::get<Args>(m_containers)) + ...);
}

int main(int argc, char* args[]) {
  Container <MyArgList> cnt;
  auto arr = cnt.getTuples<int>();
  std::cout << typeid(arr).name() << std::endl;

  cnt.get<char, int>().get<int>().push_back(5);
  arr.get<char, int>().get<int>().push_back(-99);

  std::cout << cnt.get<char, int>().get<int>() << std::endl;
  std::cout << arr.get<char, int>().get<int>() << std::endl;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 20:55:53