Разминка для мозгов: печать элементов массива
Внимание! Это довольно старый топик, посты в него не попадут в новые, и их никто не увидит. Пишите пост, если хотите просто дополнить топик, а чтобы задать новый вопрос — начните новый.
Внимание! Это довольно старый топик, посты в него не попадут в новые, и их никто не увидит. Пишите пост, если хотите просто дополнить топик, а чтобы задать новый вопрос — начните новый.
Дисклаймер: Надеюсь, что Череп простит мне использование своего бренда «Разминка для мозгов» ;)
Предлагаю решить одну простенькую задачку: вывести на печать все элементы массива. Решили? А теперь вопрос: сколькими способами это можно сделать?
Для единообразия используйте следующий шаблон:
Числа на печать выводить через один пробел:
Строка заканчивается символом конца строки, возможно с пробелом перед ним.
Каждый вариант решения размещайте в отдельном блоке. Это предотвратит взаимное влияние локальных переменных, объявленных внутри блока, на другие варианты решений.
В отличие от других «разминок», я не знаю точного ответа на поставленный вопрос. Предлагайте варианты, и будем считать.
Бесчисленное множество вариантов.
Приведу три простеньких:
http://rextester.com/FYQRR7126
Только cstdio еще не помешает включить.
Было бы интересно посмотреть и на «непростенькие» варианты.
Ещё пару вариантов
http://rextester.com/QDBJX30789
http://rextester.com/ZDJQ63966
MasterOfAlteran, по варианту от 14 ноября. Я правильно понял, что в
array_out_impl
массивfake
инициализируется нулями в количестве размера исходного массива, а как побочный результат происходит вывод на консоль элементов массиваarr
с участием операции,
?Не понял зачем нужно
Типа использование объявленной переменной? Что бы оптимизатор не порюхал? И не понял значения этого выражения.
fake
— это адрес первого элемента массива, который приводится к типуvoid
. И что получается в результате?Если этот код немного обфусцировать (только идентификаторы), то может вполне потянуть на самостоятельную «разминку для мозгов» типа «что делает этот код?».
Григорий, хотелось бы уточнить по вашему второму варианту. Я правильно понимаю, что функция
print
будет инстанцирована N-ное количество раз, где N — количество элементов в массивеary
?Да. И любой адекватный компилятор при оптимизации его выбросит, оставив только вывод.
Подавление предупреждения компилятора.
Иначе будет ругань на неиспользуемую переменную.
Такой прием много где используется.
Даже макросы делают подобные:
Например, таким же образом работает Q_UNUSED в Qt.
Вряд ли. Любой человек, знакомый с шаблонами поймет что здесь происходит без труда, а обфусцированный код никто и смотреть не будет — смысла нет, больше будешь каракули разбирать, а не в код вникать.
Переделка для C++17:
В принципе, да. Рекурсивные шаблоны очень распространенный прием.
http://rextester.com/FYQDF78100
Конкретно для этого примера можно сделать и так:
http://rextester.com/ELFTD94203
Переделка под C++17:
Плоды усилий извращённых умов поражают. А как-нибудь простенько не судьба? Типа такого:
Это слишком банально и не интересно, имхо.
Кстати говоря, я несколько удивлен. Во-первых, я думал, что будет множество как раз «простеньких» решений от новичков. Во-вторых, странно, что новички не приняли участия в разминке, хотя тема как раз для них. Кстати, кто-то из них сетовал, что «разминка для мозгов» больше не проводится. Видимо поэтому и не проводится.
MasterOfAlteran, по варианту от 18 ноября под С++17. Всё прекрасно работает с С++11 вот в таком варианте:
Но если последнюю строку заменить на
то начинает сильно ругаться по поводу невозможности создавать массив ссылок. Почему??
Потому что
decltype(*ary)
даст типint&
,а массив ссылок, как известно, создать нельзя.
Должно сработать:
C++14 —
std::remove_reference_t<decltype(*ary)>
C++11 —
typename std::remove_reference<decltype(*ary)>::type
Почему? Должен быть же просто
int
?А можно ли как-то узнать результат выполнения
decltype()
?Не должен.
decltype для выражения дает ссылку.
Смотря зачем это нужно.
Сцуко ((
Скажем в целях отладки при написании кода. Мне вот было совершенно не очевидно, что
*ary
илиary[0]
будет иметь тип ссылки. Хотя, конечно, рассуждая логически, для выражения и должна быть ссылка. Просто я*ary
как-то за выражение не посчитал: разыменование и разыменование... не сумма же ))IDE, наверное, могут тип показать.
Но, для успешного метапрограммирования систему типов
и правила вывода типов нужно знать на зубок.