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

C++如何检测模板参数是否为指定签名的函数类型

问题根源

函数名作为实参传递给模板函数时,模板参数T会被推导为函数指针类型,而非原生函数类型。你当前的类型萃取仅匹配float(float)、float(float,float)的原生函数类型,无法匹配对应的指针类型float(*)(float)、float(*)(float,float),因此始终返回false。

解决方案

方案1:修改自定义类型萃取兼容函数指针

调整类型萃取的判断逻辑,移除指针修饰后再对比类型即可:

// 单参数float返回函数判断
template<typename T, typename = void>
struct is_numeric_function1 : std::false_type {};

template<typename T>
struct is_numeric_function1<T,
    std::enable_if_t<std::is_same_v<std::remove_pointer_t<T>, float(float)>>
> : std::true_type {};

// 双参数float返回函数判断
template<typename T, typename = void>
struct is_numeric_function2 : std::false_type {};

template<typename T>
struct is_numeric_function2<T,
    std::enable_if_t<std::is_same_v<std::remove_pointer_t<T>, float(float, float)>>
> : std::true_type {};

C++17及以上版本可以新增变量模板简化调用:

template<typename T>
constexpr bool is_numeric_function1_v = is_numeric_function1<T>::value;
template<typename T>
constexpr bool is_numeric_function2_v = is_numeric_function2<T>::value;

bisect函数中直接调用即可:

constexpr bool is_function1 = is_numeric_function1_v<T>;
constexpr bool is_function2 = is_numeric_function2_v<T>;

方案2:使用标准库std::is_invocable_r(推荐)

如果需要兼容lambda、std::function等更多可调用对象,直接用标准库提供的可调用对象判断逻辑更简洁通用:

#include <type_traits>

template <typename T>
float bisect(T value, float min, float max, float tol) {
    // 判断是否可传入1个float参数调用,返回值为float类型
    constexpr bool is_function1 = std::is_invocable_r_v<float, T, float>;
    // 判断是否可传入2个float参数调用,返回值为float类型
    constexpr bool is_function2 = std::is_invocable_r_v<float, T, float, float>;

    std::cout << is_function1 << " " << is_function2 << std::endl;
    
    // 必须使用if constexpr,避免不匹配的分支代码编译报错
    if constexpr(is_function1) {
        // 单参数函数逻辑
    } else if constexpr(is_function2) {
        // 双参数函数逻辑
    }
    // 其余逻辑
}

该方案无需自定义类型萃取,兼容性更强。

内容的提问来源于stack exchange,提问作者matikowy

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 02:15:04