Я написал класс признаков, который позволяет мне извлекать информацию о аргументах и типе функции или объекта функции в С++ 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<>
. В проекте С++ 0x говорится, что тип выражения является "уникальным, неназванным, неединичным типом класса". Погрешность результата вызова typeid(...).name()
в выражении дает мне то, что кажется gcc внутренним соглашением именования для лямбда, main::{lambda(int)#1}
, а не то, что синтаксически представляет собой имя файла С++.
Короче, есть ли что-нибудь, что я могу внести в шаблон здесь:
template <typename R, typename... A>
struct function_traits<????> { ... }
который позволит этому классу признаков принимать лямбда-выражение?