且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

C ++编译时谓词,用于测试是否可以使用类型为T的参数调用类型为F的可调用对象

更新时间:2023-11-30 19:00:52

保罗答案,但遵循标准的SFINAE测试模式。再次是具有任意参数类型的一般性状 A ...

A variant of Paul's answer, but following the standard SFINAE test pattern. Again a generic trait with arbitrary parameter types A...:

struct can_call_test
{
    template<typename F, typename... A>
    static decltype(std::declval<F>()(std::declval<A>()...), std::true_type())
    f(int);

    template<typename F, typename... A>
    static std::false_type
    f(...);
};

template<typename F, typename... A>
using can_call = decltype(can_call_test::f<F, A...>(0));

然后按照您的要求执行 constexpr

Then a constexpr function as you requested:

template<typename T, typename F>
constexpr bool is_callable_with(F&&) { return can_call<F, T>{}; }

检查 live示例

这将使用函数,lambda表达式或函数对象与任意数量的参数,但对于(指针)成员函数,你必须使用 std :: result_of< F(A ...)>

This will work with functions, lambda expressions, or function objects with arbitrary number of arguments, but for (pointers to) member functions you'll have to use std::result_of<F(A...)>.

UPDATE

以下为 can_call 具有 std :: result_of 的好的函数签名语法:

Below, can_call has the nice "function signature" syntax of std::result_of:

template<typename F, typename... A>
struct can_call : decltype(can_call_test::f<F, A...>(0)) { };

template<typename F, typename... A>
struct can_call <F(A...)> : can_call <F, A...> { };

可以使用

template<typename... A, typename F>
constexpr can_call<F, A...>
is_callable_with(F&&) { return can_call<F(A...)>{}; }

其中我也做了 is_callable_with variadic(我不明白为什么它应该只限于一个参数),并返回与 can_call 相同的类型,而不是 bool $ c $

where I've also made is_callable_with variadic (I can't see why it should be limited to one argument) and returning the same type as can_call instead of bool (thanks Yakk).

再次,这里的实例