You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让编译器自动推导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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 14:55:17