関数の引数型を調べるメソッドが必要です。そのため、以下のようにclosure_traitsクラスを作成しました。具体的には、Is it possible to figure out the parameter type and return type of a lambda?からインスピレーションを受けています。C++ Lambdaにoperator()がありません
しかし、単純なラムダに適用しようとすると、 'operator()'が '(ラムダ型)'のメンバーではないというエラーが表示されます。 しかし、cppreferenceによると、ラムダにはoperator()があります。 私もstd :: functionを使ってみましたが、同等のエラーがありました。 私は何がうまくいかないのか分かりませんし、どんな助けも大歓迎です。
#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;
}
コンパイラのエラーメッセージは次のとおりです。 コンパイルコマンドは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;
なぜこれがC++ 14の悪い考えであるのか、テンプレートの 'auto'引数のために知っていますよね? 「これらの型の引数の数」を問いかけることは、しばしばより良い考えです。 – Yakk
私はあなたの質問を理解するか分からない。私は関数の引数の数とその型を推測しようとしています。なぜそれが自動車の影響を受けるのだろうか? – sangrey
あなたのデザインは基本的に '[](auto x){std :: cout << x <<" \ n ";}'をサポートすることはできません。 C++の呼び出し可能変数は固定数の引数を持ちませんし、引数の型も固定されていません。 C++で 'int'の基底を決定しようとするようなものです:' int'は基底を持っていないので、概念は実際には適用されません。あなたのケースでは、*いくつかの* callablesのために、問題を混乱させるarityとargumentの型を固定することができます。 – Yakk