![]() |
|
Модераторы: Daevaorn |
![]()
|
|
| Ivan. |
|
||||||||||||||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 291 Регистрация: 2.11.2004 Репутация: 1 Всего: 2 |
Здравствуйте коллеги.
Представьте себе, что нужно проинициализировать объект с очень сложным названием типа и передать его куда-то дальше, например в качестве аргумента функции. Пример, имеется функция принимающая объект с каким то сложным типом (для примера написал от болды):
Чтобы вызвать данную функцию с передачей объекта нужно написать следующее:
В данном случае нам пришлось снова написать название типа в точность совпадающее с ожиданиями функции. А вот бы было хорошо, если бы мы могли просто указать через запятую аргументы, а нужный конструктор бы вызвался сам, ведь он известен в качестве ожидаемого аргумента функции foo. Для этого нужно создать какой то универсальный конструктор, и выглядело бы это примерно так:
Для этого нужно, чтобы функция constructor создала бы какой то универсальный контейнер, поместила бы в него все перечисленные аргументы, а при попытке преобразовать этот контейнер к какому то типу - он попытался бы вызвать его конструктор с передачей всех вложенных в него значений. А самое важное, чтобы вся эта операция произвелать на этапе компиляции и в результате ни чем бы ни отличалась от прямого вызова конструктора. Попробуем решить эту задачу. Забегая вперед скажу, что мне это удалось. Для решения этой задачи нам понадобится универсальная переменная, способная хранить как копии объектов, так и указатели и ссылки. хотя указатель и копия в данном случае одно и тоже, а вот со ссылкой сложнее.
Данный класс позволяет принимать нам любые аргументы. Все методы имеют атрибут constexpr и могут вычисляться на этапе компиляции. Здесь все относительно просто, принимаем любой аргумент и сохраняем его копию, а в случае со ссылкой преобразовываем ее в указатель и обратно. Сама специализация необходима, чтобы отсеять аргументы по ссылке, чтобы создать универсальность, а вот без преобразования в указатель компилятор отказывается выполнять на этапе компиляции, хотя казалось бы в чем разница, храним мы в указателе или в ссылке. Дальше посложнее. На нужно создать универсальный контейнер с неограниченным числом аргументов произвольных типов:
Рекурсивный контейнер принимает неограниченное число аргументов различных типов и помещает первый аргумент к себе, а остальные во вложенный контейнер с оставшимися аргументами, пока не дойдем до последнего аргумента. Также этот контейнер имеет оператор преобразования к любому требуемому типу вызывая рекурсивный метод get с вложением всех имеющихся аргументов. Все аргументы передаются в качестве rvalue аргументов до самого конечного получателя UniversalValue, чтобы не потерять ссылки. Ну и наконец сама функция constructor
функция так же принимает неограниченное число аргументов и возвращает контейнер, который в будущем попытается преобразоваться к любому запрашиваемому типу. Ну и напоследок приведу пример:
В данном примере я передал как копию, так и ссылку и указатель и все это поместилось в кодовую память на этапе компиляции Добавлено @ 13:50 Немного оптимизировал код вложив UniversalValue в контейнер, чтобы его не было видно
Это сообщение отредактировал(а) Ivan. - 14.12.2015, 09:21 -------------------- Я могу ВСЁ, вопрос - сколько времени у меня это займет! |
||||||||||||||||
|
|||||||||||||||||
| Cheloveck |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1578 Регистрация: 26.7.2008 Где: Тула Репутация: 3 Всего: 32 |
KISS!
-------------------- ![]() |
|||
|
||||
| xvr |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 60 Всего: 223 |
Наглядный пример того, сколько можно написать кода, когда хочется сэкономить пару десятков букв из чистой лени
Хотя и красиво |
|||
|
||||
| Ivan. |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 291 Регистрация: 2.11.2004 Репутация: 1 Всего: 2 |
Велик и могуч сипипишный язык. По истине великую силу получил с++ с введением const expression и variadic template
Это сообщение отредактировал(а) Ivan. - 11.12.2015, 16:51 -------------------- Я могу ВСЁ, вопрос - сколько времени у меня это займет! |
|||
|
||||
| math64 |
|
||||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2505 Регистрация: 12.4.2007 Репутация: 8 Всего: 72 |
А ТС уверен, что код, сгенрированный таким образом не слишком усложнится. Возможно, в следующих версиях языка мы сможем написать
без всякого усложнения сгенерированного кода. |
||||
|
|||||
| Ivan. |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 291 Регистрация: 2.11.2004 Репутация: 1 Всего: 2 |
-------------------- Я могу ВСЁ, вопрос - сколько времени у меня это займет! |
|||
|
||||
![]()
|
| Правила форума "С++:Общие вопросы" | |
|
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |