如何让编译器推导可变参数继承的collection模板类型?
解决方案
要让编译器自动推导collection的模板参数,你需要自定义类模板推导指引,明确告诉编译器如何将初始化列表中的基础类型映射到对应的结构体类型。
错误原因分析
直接使用collection{5, 0.5f, "123"}时,编译器会默认把初始化列表中每个元素的类型(int、float、const char*)当作collection的模板参数。但C++不允许继承基本数据类型,因此触发“无法将基础类型作为基类”的编译错误。
实现代码
通过类型 trait 建立基础类型与结构体的映射,再配合推导指引完成自动推导:
#include <type_traits> struct A{ int a; }; struct B{ float b; }; struct C{ const char* c; }; // 类型映射trait:将基础类型关联到对应的结构体 template<typename T> struct member_struct; template<> struct member_struct<int> { using type = A; }; template<> struct member_struct<float> { using type = B; }; template<> struct member_struct<const char*> { using type = C; }; template<typename T> using member_struct_t = typename member_struct<T>::type; template<typename ... Ts> struct collection : Ts... {}; // 自定义推导指引:将初始化参数类型映射为对应的结构体类型 template<typename... Ts> collection(Ts...) -> collection<member_struct_t<Ts>...>; int main() { auto n = collection{5, 0.5f, "123"}; // 验证成员可正常访问 n.a = 10; n.b = 1.5f; n.c = "hello"; }
说明
member_structtrait 负责将每个基础类型(如int)绑定到对应的结构体(如A),确保类型映射的唯一性。- 推导指引
collection(Ts...) -> collection<member_struct_t<Ts>...>告诉编译器:当用Ts类型的参数初始化collection时,实际的模板参数是member_struct_t<Ts>(即对应的结构体)。 - 这样你就可以直接使用
collection{5, 0.5f, "123"},编译器会自动推导出collection<A,B,C>。
内容的提问来源于stack exchange,提问作者Stack Danny
相关产品推荐
相关产品推荐

