Комментарии 7
Вызов foo(1,2.3, “abcd”) инстанциируется в foo<int, double, const char*>(1, 2.3, “abcd”)
Не совсем так: тип
“abcd”
— это char const [5]
, а не const char*
Мы вынуждены обернуть функцию в структуру, чтобы обойти запрет на специализацию функций
Уточнение — на частичную специализацию функций.
По поводу Unpacking — ещё можно использовать std::make_index_sequence (14 стандарт), но можно и самому написать gens, stackoverflow
Спасибо за статью!
Не совсем так: тип “abcd” — это char const [5], а не const char*
Тогда уж наверное даже так:
char const(&)[5]
=)Уточнение — на частичную специализацию функций.
Это да, поправил…
В вебките есть реализация index_sequence. См. ближе к концу файла StdLibExtras.h
Вот она:
Такая же, как и в ответе на stackoverflow.
Вот здесь поинтересней (ещё)
366 // Compile-time integer sequences
367 // http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3658.html
368 // (Note that we only implement index_sequence, and not the more generic integer_sequence).
369 template<size_t... indexes> struct index_sequence {
370 static size_t size() { return sizeof...(indexes); }
371 };
372
373 template<size_t currentIndex, size_t...indexes> struct make_index_sequence_helper;
374
375 template<size_t...indexes> struct make_index_sequence_helper<0, indexes...> {
376 typedef std::index_sequence<indexes...> type;
377 };
378
379 template<size_t currentIndex, size_t...indexes> struct make_index_sequence_helper {
380 typedef typename make_index_sequence_helper<currentIndex - 1, currentIndex - 1, indexes...>::type type;
381 };
382
383 template<size_t length> struct make_index_sequence : public make_index_sequence_helper<length>::type { };
Такая же, как и в ответе на stackoverflow.
Вот здесь поинтересней (ещё)
Было бы крайне интересно, если бы уважаемый автор рассмотрел известные примеры использования всяческих variadric templates и лямбд с точки зрения накладных расходов. Как обычно — память и сложность алгоритмов.
То есть можно конечно сесть и прикинуть самому (это не так сложно), но готовая статейка на эту тему была бы очень кстати. Потому что работы, как обычно, выше крыши, а статья бы сэкономила массу времени. Оно бы вернулось бы Вам лучами добра от прочитавших.
Вот скажем, насколько больше памяти удобный tuple тратит по сравнению обычным struct? Прочитав наискосок реализацию, вроде, + N*sizeof(void *)?
А что с лямбдами? Все эти вызовы, насколько там много накладных? Очень интересная тема, на мой взгляд. Особенно для тех, кто пишет довольно критичный по скорости исполнения и затратам памяти код (что в случае С++, согласитесь, не так уж редко).
То есть можно конечно сесть и прикинуть самому (это не так сложно), но готовая статейка на эту тему была бы очень кстати. Потому что работы, как обычно, выше крыши, а статья бы сэкономила массу времени. Оно бы вернулось бы Вам лучами добра от прочитавших.
Вот скажем, насколько больше памяти удобный tuple тратит по сравнению обычным struct? Прочитав наискосок реализацию, вроде, + N*sizeof(void *)?
А что с лямбдами? Все эти вызовы, насколько там много накладных? Очень интересная тема, на мой взгляд. Особенно для тех, кто пишет довольно критичный по скорости исполнения и затратам памяти код (что в случае С++, согласитесь, не так уж редко).
С точки зрения накладных расходов в описанных вами примерах все хорошо, их нет =). В боевой реализации тупла нет строчки
base_type& base = static_cast<base_type&>(*this);
, поэтому sizeof(tuple<int>) == 4
. Что качается лямбд, то они, как минимум такие же быстрые в рантайме, как и обычные функции, засчет того, что лямбда — это по сути неименованный функтор с объявленным внутри класса оператором вызова, который, как известно, в таких случаях является inline
.Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Variadic templates. Tuples, unpacking and more