LINUX.ORG.RU

C++ metaprogramming

 


0

2

Скажите пожалуйста может кто в курсе. Возможно ли на плюсах с помощью шаблованов создать (к примеру контейнер) в зависимости от его применения.

Чтото в роде (даже не знаю как это правильно описать):

Если в коде применяется функции типа List.back(..) или List.size() то

typedef std::list List;
Иначе
typedef std::forward_list List;
Если это вообще возможно то киньте ссылку на нечто похожее. Или же это пока не реально ? Спасибо.


кто тут?

давай псевдокод.

Но вангую, что ты хочешь невозможного.

anonymous
()

Мне кажется, что невозможно, потому что компилятору надо знать, что за тип создавать, как только этот тип встретился, и он не может посмотреть дальше, вызывается там list.size() или нет.

hlebushek ★★
()
Ответ на: комментарий от hlebushek

Я так понимаю что компилятор со своими оптимизациями в такое не лезет. К примеру если мы создаем std::list но нам не нужены обртный порядок он всеравно создаст двухсвязный список что бы не вводить никого в заблуждение, я правильно понимаю? А в ручную мы такого сделать не можем.,?

CunMun
() автор топика
Ответ на: комментарий от CunMun

ну я так и понял.

Компилятор не может угадывать твои хотелки. Сам то как себе это представляешь? Сейчас конпелируем такой тип, потом добавляем mylist[id] = myvalue и конпелятор тебе другой тип вставляет, который умеет опертор [], исходя из твоих хотелок?

anonymous
()
Ответ на: комментарий от anonymous

Я имел ввиду чтото типа «Перегрузки типов» аля функций. В принципи я думаю что такие можно было бы реализовать на уровне компилятора. К примеру обявили два класса с одинаковым именем но с разным функционалом так же как и функции и дальше вызываем конструктор того класса который больше подходит. В принципи шаблоны и сейчас позволяют такое делать, но вот что б в зависимости от фунций членов я такого не видел. Вот и думал может есть что то чего я не знаю.

CunMun
() автор топика

Даже если и можно, зачем?

ck114
()

Или же это пока не реально ?
пока

типун тебе на язык

unsigned ★★★★
()

Как уже отметили, решение нужно принимать в месте определения типа, вперёд заглядывать нельзя. Можно сделать в таком духе:

template<typename T, bool NeedBack>
using List = std::conditional_t<NeedBack, std::list<T>, std::forward_list<T>>;
Иначе представь, как было бы весело, если то, что ты просишь, написать в хедер и заинклудить его в два исходника, так что определение типа выйдет разным.

const86 ★★★★★
()
Ответ на: комментарий от pon4ik

Оо. Это уже гораздо ближе. Там оказывается туча уже готовых всяких плюшек из серии type traits которые смело можно в constexpr. И на первый взгляд «вполне возможно». Правда надо это все изучить и переварить, а то так наскоком не осилю. Спасибо за совет.

CunMun
() автор топика
Ответ на: комментарий от const86

Да зря я надеялся. Походу действительно нереально средствами языка проверить есть ли в коде вызов той или иной функции и на основании этого передать подобный «флаг» в качестве параметра или идентификатора шаблона.

CunMun
() автор топика
Ответ на: комментарий от pon4ik

Helper types

template< bool B, class T, class F >
using conditional_t = typename conditional<B,T,F>::type;
(since C++14)

Uter
()
Последнее исправление: Uter (всего исправлений: 1)
Ответ на: комментарий от CunMun

Да зря я надеялся. Походу действительно нереально средствами языка проверить есть ли в коде вызов той или иной функции и на основании этого передать подобный «флаг» в качестве параметра или идентификатора шаблона.

Интересно, а в каких случаях это было бы выгодно?

Контейнеры принято выбирать исходя из того, что они позволяют делать наиболее эффективно. Например, vector хранит элементы последовательно, что делает перебор и прямой доступ очень эффективными, а вот операции вставки и удаления — нет. Тогда как list предоставляет эффективные операции вставки/удаления, но элементы списка могут быть «разбросаны» по памяти и при проходе по списку можно часто промахиваться мимо кэша.

Так что вопрос выбора типа контейнера обычно принимается исходя из требований задачи до написания кода.

Когда выгодно определять тип контейнера по коду, который этот код использует?

eao197 ★★★★★
()
Ответ на: комментарий от eao197

дык тс хочет тип container, для которого компилятор подставит оптимальный из стандартных.

anonymous
()

Специализируешь контейнер требуемыми типами, и в специализациях уже задаёшь нужные функции, и typedef-ы. Если я правильно понял твою хотелку.

one_more_hokum ★★★
()
Ответ на: комментарий от one_more_hokum

Да только что бы спициализация проходила автоматически на основании последующего использования. Но это к сожалению пока не реально. Компилятор в этом плане работает последавательно. Нужен предварительный дополнительный статический анализ с возможностью использовать его результатов в самом коде. Это пока не реально.

CunMun
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.