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

C++如何以模板类实例为模板参数创建可变参数类

实现方案

完全可以通过类实现同等效果,核心根据你使用的C++标准版本选择对应实现即可。

你期望的B<A<int>(1), A<float>(2.4f), A<bool>(false)>()实例化写法,本质是把A类的临时实例作为非类型模板参数传入,C++20标准对类类型非类型模板参数做了正式支持,可以完全匹配你要的写法。

C++20 完美匹配需求的实现

首先你定义的A类需要做小调整,构造函数加constexpr修饰,满足编译期常量要求:

#include <tuple>
#include <iostream>
#include <utility>

template<typename T>
class A {
public:
    T value;
    constexpr A(T v) : value(v) {}
};

类B用auto声明的非类型参数包接收所有传入的A实例,用tuple存储所有成员:

template<auto... Args>
class B {
private:
    std::tuple<decltype(Args)...> members{Args...};
public:
    // 示例:遍历打印所有持有的A实例的值
    void print_values() {
        std::apply([](const auto&... elem) {
            ((std::cout << elem.value << '\n'), ...);
        }, members);
    }
};

使用方式完全符合你的预期:

int main() {
    B<A<int>(1), A<float>(2.4f), A<bool>(false)> b;
    b.print_values();
    return 0;
}

注意点:

  • 作为非类型模板参数传入的A实例必须是编译期常量,因此A的构造函数必须是constexpr的
  • C++20要求作为非类型模板参数的类类型满足结构性条件:不能有私有/保护非静态成员、不能有虚函数、不能有虚基类,你的A类只要保持简单聚合类或者公开接口的constexpr构造即可满足要求
  • 所有持有的实例都存在tuple成员中,你可以自行添加访问、修改、遍历的逻辑

旧标准兼容方案(C11/C17)

如果你的编译环境不支持C++20,无法直接传递类类型的非类型模板参数,就不能把A实例直接写在模板尖括号里,可以用两种类型安全的替代方案:

C++11 版本:分离类型和构造参数

template<typename... Ts>
class B {
private:
    std::tuple<A<Ts>...> members;
public:
    template<typename... InitArgs>
    B(InitArgs&&... args) : members(A<Ts>(std::forward<InitArgs>(args))...) {}
};
// 实例化方式:模板参数传所有A的类型,构造函数传对应初始化值
B<int, float, bool> b(1, 2.4f, false);

C++17 版本:用CTAD简化实例化

借助C++17的类模板实参推导特性,可以做到和你写的test函数几乎一致的使用体验:

template<typename... Ts>
class B {
private:
    std::tuple<A<Ts>...> members;
public:
    B(A<Ts>... args) : members(std::move(args)...) {}
};
// 直接在构造函数传入A实例,编译器自动推导模板参数
B b(A<int>(1), A<float>(2.4f), A<bool>(false));

补充说明

你之前实现的test函数用的是C风格可变参数语法,并不是类型安全的:第一个参数会匹配为A<C>类型,后续参数属于无类型的可变参数列表,传入非A类型的值也不会触发编译错误,上面给出的所有类模板实现都是严格类型约束的,传入不符合要求的参数会直接编译失败。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 00:33:25