繁体   English   中英

如何专门化模板函数以区分空函数和非空函数参数

[英]How to specialize template function to distinguish void and non-void function arguments

我想要两个函数:接受void(*)(int)int(*)(int) 如何编写类似于 std::is_invocable_r 的 type_trait 但检查确切的返回类型(因为任何函数都可以转换为返回 void 的函数)。

#include <functional>
#include <type_traits>
#include <cstdio>

template <typename R, typename C, typename... Args>
constexpr bool is_exact_invocable_r_v =
        std::is_same_v<R, std::invoke_result_t<C, Args...>>;
        // std::is_invocable_r_v<R, C, Args...>;

template<typename C, std::enable_if_t<is_exact_invocable_r_v<int, C>, int> = 0>
void print(C)
{
    printf("1\n");
}

template<typename C, std::enable_if_t<is_exact_invocable_r_v<int, C, int>, int> = 0>
void print(C)
{
    printf("2\n");
}

template<typename C, std::enable_if_t<is_exact_invocable_r_v<void, C, int>, int> = 0>
void print(C)
{
    printf("3\n");
}

int main()
{
    print([](){return 0;});
    print([](int){return 0;});
    print([](int){});
}

std::is_invocable_r_v<R, C, Args...>会导致歧义,因为任何类型都可以std::is_invocable_r_v<R, C, Args...>为 void。

std::is_same_v<R, std::invoke_result_t<C, Args...>>导致替换失败。

问题是当C不能用Args...调用时,你的特征是不正确的,你必须 SFINAE 你的变量:

template <typename R, typename C, typename TupleArgs, typename Enabler = void>
constexpr bool is_exact_invocable_r_v_impl = false;

template <typename R, typename C, typename... Args>
constexpr bool is_exact_invocable_r_v_impl<R,
                                          C,
                                          std::tuple<Args...>,
                                          std::void_t<std::invoke_result_t<C, Args...>>> =
    std::is_same_v<R, std::invoke_result_t<C, Args...>>;

template <typename R, typename C, typename... Args>
constexpr bool is_exact_invocable_r_v =
    is_exact_invocable_r_v_impl<R, C, std::tuple<Args...>>;

演示

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM