能否依据模板参数特化命名空间?C++14技术咨询
解决C++14中隐藏B命名空间的类型映射问题
方案1:给A的类型嵌入对应B类型的别名(优先推荐)
如果能修改A命名空间下的类型定义,直接在每个类型里加个嵌套别名,把对应的B类型关联上:
namespace A { struct typeX { using b_type = B::typeX; // 直接关联B的对应类型 // 你的原有代码... }; struct typeY { using b_type = B::typeY; // 你的原有代码... }; // 以后加typeZ,就加这一行就行 struct typeZ { using b_type = B::typeZ; // 你的原有代码... }; }
然后写foo1的模板:
template<typename A_T> A_T foo1(std::vector<std::uint8_t> const& data) { using B_T = typename A_T::b_type; return foo2<B_T>(data); // 内部调用B的类型,外部完全看不到 }
调用的时候直接用A的类型指定模板参数:
A::typeX x = foo1<A::typeX>(raw_data); A::typeY y = foo1<A::typeY>(raw_data);
这种方式不用维护额外的映射表,新增类型只需要加一行别名,最省心。
方案2:用类型特征做映射(不能改A类型时用)
要是没法修改A的类型,就用特化类型特征来做映射,比写一堆重载简洁多了:
// 搞个内部细节命名空间,别让调用者看到 namespace detail { // 基础模板,只用来特化 template<typename A_T> struct map_to_b; // 给每个A的类型做特化 template<> struct map_to_b<A::typeX> { using type = B::typeX; }; template<> struct map_to_b<A::typeY> { using type = B::typeY; }; // 加新类型时,只加这一行特化 template<> struct map_to_b<A::typeZ> { using type = B::typeZ; }; // 整个别名简化写法 template<typename A_T> using map_to_b_t = typename map_to_b<A_T>::type; }
然后实现foo1:
template<typename A_T> A_T foo1(std::vector<std::uint8_t> const& data) { using B_T = detail::map_to_b_t<A_T>; return foo2<B_T>(data); }
调用方式和方案1一样,新增类型只需要加一行特化,比写重载函数省太多代码。
补充说明
- 如果
B::T不能隐式转成A::T,就在返回的时候加static_cast<A_T>(foo2<B_T>(data))就行。 - 两种方案都完全把
B命名空间藏起来了,调用者只需要知道A和foo1。
内容的提问来源于stack exchange,提问作者senior_questions_asker
相关产品推荐
相关产品推荐

