Potrzebuję metody określania typów argumentów funkcji, dlatego napisałem klasę closure_traits, podaną poniżej, zainspirowaną przez Is it possible to figure out the parameter type and return type of a lambda?.C++ Lambda nie ma operatora()
Jednak gdy próbuję zastosować to do prostej wartości lambda, pojawia się błąd, że "operator()" nie jest członkiem "(typ lambda)". Jednak, zgodnie z cppreference, lambda ma operatora(). Próbowałem także używać funkcji std :: i otrzymałem błąd równoważny. Chyba nie jestem pewien, co się dzieje, a każda pomoc będzie bardzo ceniona.
#include<type_traits>
#include<tuple>
#include<utility>
#include<iostream>
/* For generic types use the type signature of their operator() */
template <typename T>
struct closure_traits : public
closure_traits<decltype(&T::operator())> {};
/* Otherwise, we do a template match on a function type. */
template <typename ClassType, typename ReturnType,
typename... ArgTypes>
struct closure_traits<ReturnType (ClassType::*) (ArgTypes... args)>
{
using arity = std::integral_constant<std::size_t,
sizeof...(ArgTypes)>;
using Ret = ReturnType;
/* The argument types will be the same as the types of the
* elements of a tuple composed of them.
*/
template <std::size_t I>
struct Args {
using type = typename std::tuple_element<I,
std::tuple<ArgTypes...>>::type;
};
};
int main() {
auto thing = [=] (int x) {return x;};
std::cerr << "The number of arguments is "
<< closure_traits<decltype(thing)>::arity << std::endl;
return 0;
}
Komunikaty o błędach kompilatora, które dostaję, znajdują się poniżej. Moja komenda kompilacji to po prostu g ++ -std = C++ 14 main.cpp.
main.cpp: In instantiation of ‘struct closure_traits<int (main()::<lambda(int)>::*)(int) const>’:
main.cpp:9:8: required from ‘struct closure_traits<main()::<lambda(int)> >’
main.cpp:34:82: required from here
main.cpp:9:56: error: ‘operator()’ is not a member of ‘int (main()::<lambda(int)>::*)(int) const’
struct closure_traits : public closure_traits<decltype(&T::operator())> {};
^
main.cpp: In function ‘int main()’:
main.cpp:34:51: error: ‘arity’ is not a member of ‘closure_traits<main()::<lambda(int)> >’
std::cerr << "The number of arguments is " << closure_traits<decltype(thing)>::arity << std::endl;
Wiecie, dlaczego jest to zły pomysł w C++ 14, ze względu na argumenty "auto" na szablonach, prawda? Pytanie "ile argumentów tego typu" jest często lepszym pomysłem. – Yakk
Nie jestem pewien, czy rozumiem twoje pytanie. Próbuję wywnioskować liczbę argumentów funkcji i ich typów. Dlaczego miałoby to wpływać na auto? – sangrey
Twój projekt zasadniczo nie może obsłużyć '[] (auto x) {std :: cout << x <<" \ n ";}'. Callables w C++ nie mają ustalonej liczby argumentów, a ich argumenty nie mają stałych typów. To jest jak próba określenia podstawy 'int' w C++: koncepcja tak naprawdę nie ma zastosowania, ponieważ' int' nie * ma * podstawową.W twoim przypadku za * niektóre * kalki możesz mieć ustalone typy arii i argumentów, co dezorientuje problem. – Yakk