如何专门化模板函数以区分void和non-void函数参数

灯身

我想拥有2个功能:接受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_same_v<R, std::invoke_result_t<C, Args...>> 导致替换失败。

贾罗德42

问题是,在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...>>;

演示版

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何专门化模板成员函数?

来自分类Dev

带参数的Void *函数

来自分类Dev

void **指针和void * []作为函数参数

来自分类Dev

void *类型化的函数参数

来自分类Dev

如何专门化模板类成员函数?

来自分类Dev

模板成员函数专门化

来自分类Dev

模板类-成员函数专门化

来自分类Dev

模板类-成员函数专门化

来自分类Dev

函数参数中的void指针

来自分类Dev

带*&参数的递归void函数

来自分类Dev

函数参数中的void指针

来自分类Dev

如何专门化C ++中的可变参数模板函数?

来自分类Dev

C函数采用void *函数参数

来自分类Dev

如何专门化一个元组参数的函数?

来自分类Dev

专门处理返回void并且没有参数的成员函数

来自分类Dev

如何使用模板模板参数专门化类模板?

来自分类Dev

组合模板参数以形成函数签名时无效的void参数

来自分类Dev

如何在模板类中专门化模板成员函数?

来自分类Dev

如何专门化模板类中的模板成员函数(已指定)?

来自分类Dev

统一函数使用模板专门化和接口来调用实例和原始类型

来自分类Dev

使用当前类专门化继承的模板化函数

来自分类Dev

具有void * a和指针函数作为参数的函数

来自分类Dev

如何使C ++模板化函数与返回类型无关,以便将来进行专门化

来自分类Dev

如何使用模板临时参数专门化模板

来自分类Dev

使用取决于模板参数的函数指针来专门化模板

来自分类Dev

void **函数参数c ++中的指针

来自分类Dev

具有void *参数的函数原型

来自分类Dev

显式void指针作为函数参数

来自分类Dev

void const *函数中参数的目的