更新时间:2021-11-10 05:58:25
您希望将lambda转换为的函数,您可以利用 std :: is_assignable
trait:
If you know the signature of a function you want your lambda to be converted to, you can leverage the std::is_assignable
trait:
auto lambda = [] (char, double) -> int { return 0; };
using signature = int(char, double);
static_assert(std::is_assignable<signature*&, decltype(lambda)>::value, "!");
这种方法也可以与通用lambdas一起使用。
This way it can work also with generic lambdas.
我想要一个解决方案,适用于vs 2013/2015,gcc和clang
I'd like to have a solution that works for vs 2013/2015, gcc and clang
如果你不知道签名,这里是一个替代方法来检查 +
触发隐式转换。这一个利用 std :: is_assignable
测试,并验证lambda是否可分配给与lambda的函数调用操作符具有相同签名的函数指针。 (就像使用一元运算符plus的测试,这不适用于通用lambdas。但是在C ++ 11中没有通用的lambdas)。
If you don't know the signature, here's an approach that is an alternative to checking whether +
triggers an implicit conversion. This one exploits the std::is_assignable
test and verifies whether a lambda is assignable to a function pointer with the same signature as the lambda's function call operator. (Just like a test with unary operator plus, this doesn't work with generic lambdas. But in C++11 there are no generic lambdas).
#include <type_traits>
template <typename T>
struct identity { using type = T; };
template <typename...>
using void_t = void;
template <typename F>
struct call_operator;
template <typename C, typename R, typename... A>
struct call_operator<R(C::*)(A...)> : identity<R(A...)> {};
template <typename C, typename R, typename... A>
struct call_operator<R(C::*)(A...) const> : identity<R(A...)> {};
template <typename F>
using call_operator_t = typename call_operator<F>::type;
template <typename, typename = void_t<>>
struct is_convertible_to_function
: std::false_type {};
template <typename L>
struct is_convertible_to_function<L, void_t<decltype(&L::operator())>>
: std::is_assignable<call_operator_t<decltype(&L::operator())>*&, L> {};
测试:
int main()
{
auto x = [] { return 5; };
auto y = [x] { return x(); };
static_assert(is_convertible_to_function<decltype(x)>::value, "!");
static_assert(!is_convertible_to_function<decltype(y)>::value, "!");
}