Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[35.173.48.18] |
|
Сообщ.
#1
,
|
|
|
Всем добрый день!
Недавно знакомился с документацией матричной библиотеки шаблонов Eigen и был удивлен ее возможностями... Создавая объект матрицы можно задать ее размер и она выделит память либо на стеке, либо в куче в зависимости от значений аргументов (которые за это отвечают). Стало интересно как это реализовано, но там черт ногу сломит в коде. Может кто-нибудь может на пальцах объяснить, как это можно сделать в С++? Всего хорошего! |
Сообщ.
#2
,
|
|
|
Цитата Fedel @ Создавая объект матрицы можно задать ее размер и она выделит память либо на стеке, либо в куче в зависимости от значений аргументов (которые за это отвечают). Кроме основной формы new используется размещающий оператор new. тут можно почитать Исходник может выглядеть так: //... char BufferInStack[16384]; BOOL Stack = ...; char *pBuf; if(Stack) {pBuf = new (BufferInStack) char [sizeData];} else {pBuf = new char [sizeData];} Возможны варианты. Можно сделать 2 комплекса процедур, выполняющих одну и ту же работу. Один комплекс использует исключительно стек, другой - кучу. |
Сообщ.
#3
,
|
|
|
Цитата Fedel @ Политиками. Или, как их иногда называют, стратегиями. Параметром шаблона приходит класс, который реализует по-своему требуемое поведение. Очень похоже на полиморфизм, только не ран-таймовый, а компайл-таймовый. Нередко его так и называют: статический полиморфизм.Создавая объект матрицы можно задать ее размер и она выделит память либо на стеке, либо в куче в зависимости от значений аргументов (которые за это отвечают). Стало интересно как это реализовано, но там черт ногу сломит в коде. Может кто-нибудь может на пальцах объяснить, как это можно сделать в С++? Вот синтетический пример (не компилировал даже, просто демонстрация возможности): template <size_t Size> class HeapStorage { std::vector<unsigned char> storage; public: HeapStorage() { storage.resize(Size); } void* getBase(){ return &storage.front(); } }; template <size_t Size> class StackStorage { std::array<unsigned char, Size> storage; public: void* getBase(){ return &storage.front(); } }; template <size_t Size, template<size_t> class MemoryPolicy> class StorageHolder: MemoryPolicy<Size> { }; /* использование */ void f() { StorageHolder<1024, StackStorage> lowMemoryUsing; StorageHolder<1024*1024*1024, HeapStorage> highMemoryUsing; /* ... */ } |
Сообщ.
#4
,
|
|
|
Цитата ЫукпШ @ Кроме основной формы new используется размещающий оператор new. Да, такой подход возможен, но мне кажется, что для матричной библиотеки заранее захватить объект стека не очень хорошо. Кроме того, я не видел, чтобы в документации были ограничения на выделяемую память, вызванные тем, что мы захватываем предопределенный на момент компиляции размер. Добавлено Цитата Qraizer @ Шаблоны, в отличие от дженериков, гораздо более богаты возможностями. С Вами трудно не согласиться. То что я понял в коде, что шаблон класса матрицы наследуется от класса, который параметризуется этим же классом матрицы. Поэтому в исходном коде я и поплыл... |
Сообщ.
#5
,
|
|
|
Цитата Fedel @ Curiosily Reccurring Template Pattern (CRTP) То что я понял в коде, что шаблон класса матрицы наследуется от класса, который параметризуется этим же классом матрицы. |
Сообщ.
#6
,
|
|
|