如何让编译器自动推导c_str_array_eq类模板的模板参数?
如何让编译器自动推导谓词的模板参数?
我编写了一个可用于find_if的谓词,用于在std::array(或类数组对象)的集合中搜索C风格字符串:
template <class Array> class c_str_array_eq { static_assert(std::predicate<c_str_array_eq, const Array &>); const char *str; public: explicit constexpr c_str_array_eq(const char *str) : str{str} {} bool operator()(const Array &array) const { return std::strncmp(str, array.data(), array.size()) != 0; } };
但使用时必须显式指定模板参数,写法繁琐:
struct my_object { std::array<char, 256> str; }; std::ranges::find_if(a_collection, c_str_array_eq<std::array<char, 256>>("foo"), &my_object::str);
请问如何让编译器自动推导c_str_array_eq的模板参数?
解决方案:将类模板改为带模板调用运算符的普通类
原来的问题在于,类模板的模板参数Array只能通过构造函数的参数推导,但构造函数仅接收const char*,无法关联到Array类型。我们可以调整结构,让类本身不是模板,而是将operator()设为模板函数,这样调用时编译器会自动推导Array类型:
#include <concepts> #include <cstring> class c_str_array_eq { const char* str; public: explicit constexpr c_str_array_eq(const char* str) : str{str} {} template <class Array> requires requires(const Array& arr) { { arr.data() } -> std::convertible_to<const char*>; { arr.size() } -> std::convertible_to<std::size_t>; } bool operator()(const Array& array) const { // 注意:若要匹配相等的元素,应改为 == 0 return std::strncmp(str, array.data(), array.size()) != 0; } };
现在使用时无需指定模板参数,直接传入字符串即可:
std::ranges::find_if(a_collection, c_str_array_eq("foo"), &my_object::str);
补充说明
- 我们用
requires约束替代了原有的static_assert,更符合C++20概念的使用规范,明确限定Array必须提供data()和size()方法,且返回值符合要求。 - 若你的需求是查找与目标字符串相等的元素,需要将
std::strncmp的判断条件从!= 0改为== 0,避免逻辑反向。
内容的提问来源于Stack Exchange,提问作者MTCoster
相关产品推荐
相关产品推荐

