(no subject)
Dec. 13th, 2016 02:29 amВ последние дни опробовал парочку новых для себя приемов в программировании совсем в разных областях: запустил coroutine в скриптах Lua внутри моего приложения и понял как использовать шаблоны C++ с переменным числом аргументов.
Coroutine дает возможность создавать программы с несколькими точками входа и выхода внутри, что удобно, например, для обработки удаленных данных и позволяет снаружи обеспечивать работу скрипта используя вызов всего одной функции.
А variadic шаблоны C++ позволяют нынче делать совсем уже прежде немыслимые вещи для статически типизированного языка - создавать функции с переменным числом аргументов любых типов и получать внутри доступ ко всем этим аргументам через перебор. Крутотень! Сейчас, правда, код выглядит слегка перегруженным, потому что в современном C++ нет стандартных методов перебора элементов кортежа, но, надеюсь, они скоро будут и тогда код упростится совсем.
Coroutine дает возможность создавать программы с несколькими точками входа и выхода внутри, что удобно, например, для обработки удаленных данных и позволяет снаружи обеспечивать работу скрипта используя вызов всего одной функции.
А variadic шаблоны C++ позволяют нынче делать совсем уже прежде немыслимые вещи для статически типизированного языка - создавать функции с переменным числом аргументов любых типов и получать внутри доступ ко всем этим аргументам через перебор. Крутотень! Сейчас, правда, код выглядит слегка перегруженным, потому что в современном C++ нет стандартных методов перебора элементов кортежа, но, надеюсь, они скоро будут и тогда код упростится совсем.
// Пример реализации кода функции логгера с переменным числом аргументов
// мопед не мой - нашел на StackOverflow и использовал идею у себя
#include <tuple>
#include <utility>
#include <iostream>
template<std::size_t N> struct tuple_functor {
template<typename T, typename F> static void run(size_t i, T&& t, F&& f) {
const std::size_t I = (N - 1);
switch (i) {
case I:
std::forward<F>(f)(std::get<I>(std::forward<T>(t)));
break;
default:
tuple_functor<I>::run(i, std::forward<T>(t), std::forward<F>(f));
}
}
};
template<> struct tuple_functor<0> {
template<typename T, typename F>
static void run(std::size_t, T, F) {}
};
template<typename ... T> void logger(T ... args) {
const std::size_t num = sizeof ... (T);
auto my_tuple = std::forward_as_tuple(args ...);
auto do_sth = [](const auto& elem) {
std::cout << elem << std::endl;
};
for (int i = 0; i < num; ++i)
tuple_functor<num>::run(i, my_tuple, do_sth);
}
int main() {
logger("adbc", 123, "xf", 2.0);
return 0;
}