如何为不可修改类添加标签以实现C++函数分派(C++11/14兼容)
解决方案:通过模板特化扩展类型检测
要在不修改HiddenObject类定义的前提下让is_some_specific_object_type<HiddenObject<T>>::value == true,最直接的方式是给is_some_specific_object_type模板添加针对HiddenObject的部分特化版本:
// 针对HiddenObject<T>的部分特化 template<typename T> struct is_some_specific_object_type<HiddenObject<T>> { static constexpr bool value = true; };
原理说明
原来的is_some_specific_object_type通用模板默认返回false,而新增的部分特化版本会优先匹配HiddenObject<T>类型的实例,直接将value设为true,完全绕开了对类内部ObjectTag的检测逻辑。
完整验证代码
将这段特化代码加入原有代码后,测试效果如下:
#include <iostream> #include <type_traits> // 原有标签定义 struct SomeSpecificObjectType{}; // 原有Object类 template<typename T> class Object { public: Object(T&& in) : m_data(in) {}; typedef SomeSpecificObjectType ObjectTag; T m_data; }; // 原有OtherObject类 template<typename T> class OtherObject { public: OtherObject(T&& in) : m_data(in) {}; T m_data; }; // 无法修改的HiddenObject类 template<typename T> class HiddenObject { public: HiddenObject(T&& in) : m_data(in) {}; T m_data; }; // 原有类型检测模板通用版本 template<typename T, typename Enable=void> struct is_some_specific_object_type { static constexpr bool value = false; }; // 原有检测ObjectTag的偏特化版本 template<typename T> struct is_some_specific_object_type<T, typename std::enable_if<std::is_same<typename T::ObjectTag, SomeSpecificObjectType>::value>::type> { static constexpr bool value = true; }; // 新增:针对HiddenObject<T>的部分特化 template<typename T> struct is_some_specific_object_type<HiddenObject<T>> { static constexpr bool value = true; }; // 原有函数分派逻辑 template<typename T, typename std::enable_if<!is_some_specific_object_type<T>::value>::type* = nullptr> void some_func(const T & data) { std::cout << "something" << std::endl; } template<typename T, typename std::enable_if<is_some_specific_object_type<T>::value>::type* = nullptr> void some_func(const T & data) { std::cout << "something else" << std::endl; } // 测试代码 int main() { Object<int> obj(1); OtherObject<int> other(2); HiddenObject<int> hidden(3); some_func(obj); // 输出:something else some_func(other); // 输出:something some_func(hidden); // 输出:something else(符合需求) return 0; }
进阶:针对特定参数的HiddenObject特化
如果只需要让HiddenObject<int>被识别,其他HiddenObject<T>不被识别,可以写成全特化版本:
template<> struct is_some_specific_object_type<HiddenObject<int>> { static constexpr bool value = true; };
内容的提问来源于stack exchange,提问作者somewhat_clueless_developer
相关产品推荐
相关产品推荐

