Главная страница Случайная страница Разделы сайта АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника |
💸 Как сделать бизнес проще, а карман толще?
Тот, кто работает в сфере услуг, знает — без ведения записи клиентов никуда. Мало того, что нужно видеть свое раписание, но и напоминать клиентам о визитах тоже.
Проблема в том, что средняя цена по рынку за такой сервис — 800 руб/мес или почти 15 000 руб за год. И это минимальный функционал.
Нашли самый бюджетный и оптимальный вариант: сервис VisitTime.⚡️ Для новых пользователей первый месяц бесплатно. А далее 290 руб/мес, это в 3 раза дешевле аналогов. За эту цену доступен весь функционал: напоминание о визитах, чаевые, предоплаты, общение с клиентами, переносы записей и так далее. ✅ Уйма гибких настроек, которые помогут вам зарабатывать больше и забыть про чувство «что-то мне нужно было сделать». Сомневаетесь? нажмите на текст, запустите чат-бота и убедитесь во всем сами! String s;
Int i; while(cin> > s> > i) vp.emplace_back(s, i);
Очевидно, что контейнеры – это не единственное место стандартной библиотеки, которое пользуется преимуществами новых языковых возможностей. Так, например:
Аллокаторы с дополнительным состоянием Для простоты и компактности контейнеров С++98 не требует от них поддержки аллокаторов с состоянием. Аллокаторы не должны были хранится в объектах контейнеров. Такое поведение все еще используется по умолчанию в С++11, но появилась возможность использования аллокаторов с состоянием, например, можно использовать аллокатор, содержащий указатель на область памяти из которой происходит выделение. Например: // Вариант для C++98не содержит данных template< class T> class Simple_alloc { // обычная реализация аллокатора }; class Arena { void* p; Int s; public: Arena(void* pp, int ss); // выделяет из диапазона p[0..ss-1] }; template< class T> struct My_alloc { Arena& a; My_alloc(Arena& aa): a(aa) { } // обычная реализация аллокатора }; Arena my_arena1(new char[100000], 100000); Arena my_arena2(new char[1000000], 1000000); // память выделяется аллокатором по умолчанию vector< int> v0; // выделяет из my_arena1 vector< int, My_alloc< int> > v1(My_alloc< int> {my_arena1}); // выделяет из my_arena2 vector< int, My_alloc< int> > v2(My_alloc< int> {my_arena2}); // выделяет с помощью Simple_alloc vector< int, Simple_alloc< int> > v3;
Обычно, для облегчения синтаксиса используют typedef. Нет никакой гарантии того, что Simple_alloc и аллокатор, используемый по умолчанию столкнутся с нехваткой памяти, но это можно гарантировать с помощью небольшого количества метапрограммирования шаблонов. Таким образом, использование аллокатора приводит к дополнительному расходу памяти только в том случае, когда аллокатор обладает состоянием (как My_alloc). При использовании пользовательских аллокаторов с контейнерами может возникнуть одна коварная проблема: должен ли элемент располагаться в той же самой выделенной области, что и контейнер? Например, если вы используете Your_allocator для Your_string для выделения его элементов, и я использую My_allocator для выделения элементов в объекте My_vector, тогда какой аллокатор должен использоваться для элементов в типе My_vector< Your_allocator> >? Решение заключается в возможности указать контейнеру какой аллокатор должен передаваться его элементам. Например, предположим, что у меня есть аллокатор My_alloc и я хочу, чтобы vector< string> использовал My_alloc дляэлементов вектора и для выделения элементов строки. Прежде всего, нужно создать версию строки с My_alloc. // строка с нужным аллокатором using xstring = basic_string< char, char_traits< char>, My_alloc< char> >;
Затем, мне нужно создать версию vector, принимающую строки и My_alloc, и передающий этот аллокатор строке: using svec = vector< xstring, scoped_allocator_adaptor< My_alloc< xstring> > >;
Теперь мы можем создать аллокатор типа My_alloc< xstring>: svec v(svec:: allocator_type(My_alloc< xstring> {my_arena1}));
Теперь svec – это вектор строк, который использует My_alloc для выделения памяти для своих элементов. Новое поведение заключается в использовании «адаптера» (“wrapper”) из стандартной библиотеки под названием scoped_allocator_adaptor, который указывает на то, что строки также должны использовать My_alloc. Обратите внимание, что адаптер может (очень легко) преобразовывать My_alloc< xstring>, требуемый типу xstring. Так что у нас есть 4 варианта: // vector и string используют свой собственный // аллокатор (аллокатор по умолчанию): using svec0 = vector< string>;
|