如何仅在模板类型含data和size成员函数时启用构造函数?
解决方案
C++20及以上(简洁方案)
利用C++20引入的requires约束,直接在模板构造函数上添加条件,确保传入的类型T拥有符合要求的data()和size()成员函数:
#include <concepts> struct MyStructure { MyStructure(char* d, int size) {} template <typename T> requires requires(T&& rhs) { // 检查rhs有data()成员,且返回值可转换为char* { rhs.data() } -> std::convertible_to<char*>; // 检查rhs有size()成员,且返回值可转换为int { rhs.size() } -> std::convertible_to<int>; } MyStructure(T&& rhs) : MyStructure(rhs.data(), rhs.size()) {} };
这里的双层requires是C++20的语法:外层用于约束模板的实例化,内层通过表达式验证确认类型具备所需成员函数,同时还能检查返回值的兼容性。
C11/C17兼容方案
借助SFINAE(替换失败并非错误)机制,结合std::enable_if和类型特性(trait)实现条件启用:
基础版本(仅检查成员存在)
#include <type_traits> // 定义类型特性,判断T是否拥有data()和size()成员 template <typename T, typename = void> struct has_data_and_size : std::false_type {}; template <typename T> struct has_data_and_size<T, std::void_t< decltype(std::declval<T>().data()), decltype(std::declval<T>().size()) >> : std::true_type {}; struct MyStructure { MyStructure(char* d, int size) {} // 仅当has_data_and_size<T>::value为true时,此构造函数才会被启用 template <typename T, typename = std::enable_if_t<has_data_and_size<T>::value>> MyStructure(T&& rhs) : MyStructure(rhs.data(), rhs.size()) {} };
增强版本(同时检查返回值兼容性)
如果需要确保data()和size()的返回值能适配第一个构造函数的参数,可以扩展类型特性:
#include <type_traits> template <typename T, typename = void> struct has_valid_data_and_size : std::false_type {}; template <typename T> struct has_valid_data_and_size<T, std::void_t< decltype(std::declval<T>().data()), decltype(std::declval<T>().size()) >> : std::conjunction< // 检查data()返回值可转换为char* std::is_convertible<decltype(std::declval<T>().data()), char*>, // 检查size()返回值可转换为int std::is_convertible<decltype(std::declval<T>().size()), int> > {}; struct MyStructure { MyStructure(char* d, int size) {} template <typename T, typename = std::enable_if_t<has_valid_data_and_size<T>::value>> MyStructure(T&& rhs) : MyStructure(rhs.data(), rhs.size()) {} };
内容的提问来源于stack exchange,提问作者Wad
相关产品推荐
相关产品推荐

