gpt4 book ai didi

c++ - 是否可以找出多态 C++ 14 lambda 的参数类型和返回类型?

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:43:19 25 4
gpt4 key购买 nike

从这个问题(Is it possible to figure out the parameter type and return type of a lambda?)开始,我大量使用了建议的function_traits。然而,随着 C++14 的出现,多态 lambda 表达式出现了,它们让我很为难。

template <typename T>
struct function_traits
: public function_traits<decltype(&T::operator())>
{};
// For generic types, directly use the result of the signature of its 'operator()'

template <typename ClassType, typename ReturnType, typename... Args>
struct function_traits<ReturnType(ClassType::*)(Args...) const>
// we specialize for pointers to member function
{
enum { arity = sizeof...(Args) };
// arity is the number of arguments.

typedef ReturnType result_type;

template <size_t i>
struct arg
{
typedef typename std::tuple_element<i, std::tuple<Args...>>::type type;
// the i-th argument is equivalent to the i-th tuple element of a tuple
// composed of those arguments.
};
};

在另一个问题的答案中提出的 operator() 现在按照标准中的规定重载以支持:

auto lambda1 = [](auto& a) { a.foo(); } 

auto lambda2 = [](auto&&... args) { foo(args...); };

此重载现在将 function_traits 类分开,因为编译器无法解析正确版本的 operator()

lambda.cpp:98:38: error: reference to overloaded function could not be
resolved; did you mean to call it?
typedef function_traits<decltype(&T::operator())> caller;

是否可以通过 C++14 在多态 lambda 上实现 function_traits 的功能?

最佳答案

这在一般意义上目前是不可能做到的,但是如果您的 lambda 对它们的所有参数都有 auto 并且可以将所有参数替换为某种已知类型,那么您可以修改这个问题的答案: C++ metafunction to determine whether a type is callable

按照

static const bool OneArg = (sizeof( test<T, int>(0)  ) == 1);
static const bool TwoArg = (sizeof( test<T, int, int>(0) ) == 1);
static const bool ThreeArg = (sizeof( test<T, int, int, int>(0) ) == 1);
static constexpr std::size_t TemplatedOperatorArgSize =
OneArg
? 1
: TwoArg
? 2
: ThreeArg
? 3
: -1;

为嵌套的三元组道歉。然后用这样的东西来调用它:

template<size_t N, typename T>
struct Apply {
template<typename F, typename... A>
static inline decltype(auto) apply(F && f, A &&... a) {
return Apply<N-1, T>::apply(::std::forward<F>(f), std::declval<T>(), ::std::forward<A>(a)...);
}
};

template<typename T>
struct Apply<0, T> {
template<typename F, typename... A>
static inline decltype(auto) apply(F && f, A &&... a) {
return invoke(std::forward<F>(f), std::forward<A>(a)...);
}
};

template<std::size_t Size, typename T, typename F>
inline decltype(auto) apply(F && f) {
return Apply<Size, T>::apply(::std::forward<F>(f));
}

使用调用自:http://en.cppreference.com/w/cpp/utility/functional/invoke

获取返回类型

using return_type = decltype(
apply<has_callable_operator<T>::TemplatedOperatorArgSize, int>(function)
);

可以使用 std::make_index_sequence 重写第一部分以处理任意数量的参数

但总的来说,我会说你正掉入兔子洞。祝你好运。

注意:没有测试应用代码,但它应该足以让你继续。

编辑:另外,返回类型需要独立于参数类型才能实现你想要的

关于c++ - 是否可以找出多态 C++ 14 lambda 的参数类型和返回类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28105371/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com