Pull to refresh

Comments 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] =)
Уточнение — на частичную специализацию функций.

Это да, поправил…
Не наверное, а точно!
И в случае с foo(1,2.3, “abcd”) тип 3го аргумента шаблона действительно выведется в const char*. Простите, я невнимателен.
В вебките есть реализация index_sequence. См. ближе к концу файла StdLibExtras.h
Вот она:
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 *)?
А что с лямбдами? Все эти вызовы, насколько там много накладных? Очень интересная тема, на мой взгляд. Особенно для тех, кто пишет довольно критичный по скорости исполнения и затратам памяти код (что в случае С++, согласитесь, не так уж редко).
С точки зрения накладных расходов в описанных вами примерах все хорошо, их нет =). В боевой реализации тупла нет строчки base_type& base = static_cast<base_type&>(*this);, поэтому sizeof(tuple<int>) == 4. Что качается лямбд, то они, как минимум такие же быстрые в рантайме, как и обычные функции, засчет того, что лямбда — это по сути неименованный функтор с объявленным внутри класса оператором вызова, который, как известно, в таких случаях является inline.
Sign up to leave a comment.

Articles

Change theme settings