C++多模板参数类如何仅传单个参数完成依赖参数自动匹配
实现方案
两种常用的实现方式如下:
方案1:给原类模板的第二个参数设置默认类型(最简便,推荐优先使用)
先定义一个类型映射traits模板,建立T和对应B类型的关联,再将原类模板的第二个参数默认值设为traits的查询结果即可:
// 1. 定义类型映射traits template<class T> struct Vector2BaseType {}; template<> struct Vector2BaseType<float> { using type = XMFLOAT2; }; template<> struct Vector2BaseType<int32_t> { using type = XMINT2; }; template<> struct Vector2BaseType<uint32_t> { using type = XMUINT2; }; // 2. 修改原类模板声明,给第二个参数加默认值 template <class T, class B = typename Vector2BaseType<T>::type> struct Vector2 : B { Vector2() noexcept; constexpr explicit Vector2(T a) noexcept; }; // 原有的显式实例化无需修改,依然有效 template class Vector2<float, XMFLOAT2>; template class Vector2<int32_t, XMINT2>; template class Vector2<uint32_t, XMUINT2>;
修改后可以直接使用Vector2<float>的写法,编译器会自动匹配第二个参数为XMFLOAT2,同时原有的Vector2<float, XMFLOAT2>写法也完全兼容。
方案2:使用别名模板(适用于无法修改原双参数Vector2定义的场景)
如果不能改动原双参数Vector2的声明,可以单独对外暴露单参数的别名模板:
// 先定义和方案1一致的类型映射traits template<class T> struct Vector2BaseType {}; template<> struct Vector2BaseType<float> { using type = XMFLOAT2; }; template<> struct Vector2BaseType<int32_t> { using type = XMINT2; }; template<> struct Vector2BaseType<uint32_t> { using type = XMUINT2; }; // 定义单参数别名模板,如果要和原类同名,可以把原双参数类模板放到内部命名空间 namespace detail { template <class T, class B> struct Vector2 : B { Vector2() noexcept; constexpr explicit Vector2(T a) noexcept; }; // 显式实例化也放到detail命名空间下 template class Vector2<float, XMFLOAT2>; template class Vector2<int32_t, XMINT2>; template class Vector2<uint32_t, XMUINT2>; } // 对外暴露的单参数别名 template<class T> using Vector2 = detail::Vector2<T, typename Vector2BaseType<T>::type>;
注意事项
- 后续如果要新增支持的T类型,只需要新增对应的
Vector2BaseType特化即可,不需要修改核心逻辑 - 两种方案都兼容你已经写好的显式实例化,不会影响编译效率和二进制体积
内容的提问来源于stack exchange,提问作者J.Paravicini
相关产品推荐
相关产品推荐

