如何在C++模板类中基于模板参数条件实现模板函数
解决方案
要实现仅当should_use_c_cast == true时才允许实例化cast()方法,可通过以下几种方式实现:
方法1:显式特化成员函数模板
针对should_use_c_cast=true的场景显式特化cast()方法,当模板参数为false时,编译器会因找不到对应实现而阻止调用:
// 原类定义保持不变 template <size_t size_of_allocated_memory_in_bytes> class malloc_ptr { private: void* ptr; public: malloc_ptr() : ptr(malloc(size_of_allocated_memory_in_bytes)) {} template <typename cast_type , bool should_use_c_cast> cast_type cast(); ~malloc_ptr() noexcept { free(ptr); } }; // 仅特化should_use_c_cast=true的情况 template<size_t size_of_allocated_memory_in_bytes> template<class cast_type> cast_type malloc_ptr<size_of_allocated_memory_in_bytes>::cast<cast_type, true>() { return reinterpret_cast<cast_type>(ptr); }
方法2:使用SFINAE(C++11及以上)
借助std::enable_if在编译阶段过滤掉should_use_c_cast=false的无效情况:
#include <type_traits> template <size_t size_of_allocated_memory_in_bytes> class malloc_ptr { private: void* ptr; public: malloc_ptr() : ptr(malloc(size_of_allocated_memory_in_bytes)) {} // 仅当should_use_c_cast为true时,该函数模板才会被编译器识别 template <typename cast_type , bool should_use_c_cast, typename = std::enable_if_t<should_use_c_cast>> cast_type cast(); ~malloc_ptr() noexcept { free(ptr); } }; template<size_t size_of_allocated_memory_in_bytes> template<class cast_type, bool should_use_c_cast, typename> cast_type malloc_ptr<size_of_allocated_memory_in_bytes>::cast() { return reinterpret_cast<cast_type>(ptr); }
方法3:使用C++20 requires表达式
C++20的requires表达式可更直观地声明函数的可用条件:
template <size_t size_of_allocated_memory_in_bytes> class malloc_ptr { private: void* ptr; public: malloc_ptr() : ptr(malloc(size_of_allocated_memory_in_bytes)) {} // 直接限定仅允许should_use_c_cast=true的情况 template <typename cast_type , bool should_use_c_cast> requires (should_use_c_cast == true) cast_type cast(); ~malloc_ptr() noexcept { free(ptr); } }; template<size_t size_of_allocated_memory_in_bytes> template<class cast_type, bool should_use_c_cast> requires (should_use_c_cast == true) cast_type malloc_ptr<size_of_allocated_memory_in_bytes>::cast() { return reinterpret_cast<cast_type>(ptr); }
内容的提问来源于stack exchange,提问作者Amrit Sanjeev
相关产品推荐
相关产品推荐

