Я искал SO и другие форумы, которые ищут способ определения параметров и типа возврата лямбда, а затем действуют на эти параметры, чтобы выполнить поиск типов при репо объектов, которые уже были созданы. Дело в том, чтобы создать способ делать инъекцию зависимостей на каком-либо произвольно определенном лямбда-выражении. Например, если у меня есть что-то вроде следующего:compile time loop over templated type
auto lambda = [] (MyObject o) -> string { return o.name(); };
Я мог бы определить типы параметров лямбда, и поиска соответствующего объекта типа MyObject
, а затем вызвать 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.
};
};
который я нашел в this SO пост (очень аккуратно).
Теперь, что я хотел бы сделать, это реализовать какое-то время компиляции эквивалент следующее:
// first get the type of the lambda using the above 'function_traits' template
typedef function_traits<decltype(lambda)> traits;
// now iterate over the traits and get the type of each argument, then print out the type name
for (size_t i = 0u; i < size_t(traits::arity); ++i)
{
// The point to focus on here is `traits::args<i>::type`
std::cout << typeid(traits::args<i>::type).name() << std::end;
}
То, что я писал выше, невозможно. Проблема в приведенном выше коде заключается в том, что i
не является константой и оценивается во время выполнения, в отличие от времени компиляции (где оценивается остальная часть магии шаблона). Я попробовал несколько разных вещей, чтобы попытаться выяснить, как это сделать (рекурсия шаблонов среди них), но я не смог найти решение, которое делает именно то, что я хочу.
Итак, корень моего вопроса на самом деле, как вы «перебираете» по шаблону? Я новичок в TMP, и сделать умственный переход от времени выполнения к логике компиляции - это сложная задача. Если у кого-то есть предложения для новичка, это было бы здорово.
Цикл в целом вы можете omplish с помощью шаблона class Loop {...} ', который делегирует' Loop 'для следующей итерации и шаблон специализации класс Loop {...}' для прекращения но мне пришлось бы немного погрузиться в проблему, чтобы выяснить, как применить ее к этому делу. –
cdhowie
Существует два типичных подхода к этой проблеме: рекурсия и расширение пакета с использованием трюков индексов. К сожалению, вы не говорите нам, какие проблемы у вас были с рекурсией или с тем, что вы пробовали с рекурсией. Для трюков индексов см., Например, http://stackoverflow.com/a/7858971 – dyp
Вы даже можете найти несколько вопросов под названием «Итерации над кортежем» или аналогичные в SO, например. http://stackoverflow.com/q/1198260 – dyp