C++0x の関数または関数オブジェクトの引数と型に関する情報を抽出できるようにする特性クラスを作成しました (gcc 4.5.0 でテスト済み)。一般的なケースでは、関数オブジェクトを処理します。
template <typename F>
struct function_traits {
template <typename R, typename... A>
struct _internal { };
template <typename R, typename... A>
struct _internal<R (F::*)(A...)> {
// ...
};
typedef typename _internal<decltype(&F::operator())>::<<nested types go here>>;
};
次に、グローバル スコープでプレーンな関数を特殊化します。
template <typename R, typename... A>
struct function_traits<R (*)(A...)> {
// ...
};
これは正常に機能し、関数をテンプレートまたは関数オブジェクトに渡すことができ、適切に機能します。
template <typename F>
void foo(F f) {
typename function_traits<F>::whatever ...;
}
int f(int x) { ... }
foo(f);
関数または関数オブジェクトを に渡す代わりにfoo
、ラムダ式を渡したい場合はどうすればよいですか?
foo([](int x) { ... });
ここでの問題は、どちらの特殊化もfunction_traits<>
当てはまらないことです。C++0x ドラフトでは、式の型は「一意で名前のない非共用体クラス型」であると述べています。式を呼び出した結果をデマングリングすると、構文的に C++ 型名を表すものではなくtypeid(...).name()
、ラムダに対する gcc の内部命名規則のように見えるものが得られます。main::{lambda(int)#1}
要するに、ここのテンプレートに入れることができるものはありますか:
template <typename R, typename... A>
struct function_traits<????> { ... }
この特性クラスがラムダ式を受け入れることを許可しますか?