Pull to refresh
5
0
Андрей @AndrewAZ

User

Send message

Использование boost::variant для описания состояний модели

Reading time3 min
Views10K
В моделях данных очень часто требуется хранить некоторые переключаемые состояния. Классический способ в С++ для этого — использование перечислимых типов enum.

Например, если у вас в программе пользователь может переключаться между двумя экранами, вы заводите enum screen { screen_one, screen_two }; и переменную screen cur_screen_. Отрисовщик должен получить у модели «текущий выбранный экран», и затем отрисовать его, запрашивая у модели дополнительные данные, относящиеся именно к этому экрану. Что-то вроде:

switch (model.cur_screen())
{
case screen_one:
  model.get_screen_one_elements();
  ...
case screen_two:
  model.get_screen_two_elements();
  ...
}


При использовании такой модели, программист может запрашивать данные, которые для текущего состояния совершенно не актуальны. Например, вызвать метод get_screen_two_elements() для получения списка элементов второго экрана, когда текущий экран — первый. Хорошей практикой является использование ассертов вида ASSERT(cur_screen_ == screen_one) в методах, зависимых от конкретного экрана. Это обеспечивает некоторый контроль времени выполнения.

Но есть способ обеспечить контроль времени компиляции и более явное разделение состояний с помощью boost::variant.

Читать дальше →
Total votes 24: ↑22 and ↓2+20
Comments17

DSL для boost::MPL, превращаем f(x) в f<x>::type

Reading time2 min
Views3.4K
Краткое содержание статьи (для тех кто знаком с boost::mpl), typename опущены для ясности:
a = b;				==>		typedef b a;
f(x)				==>		f<x>::type
f(x) { return x*; }		==>		template<typename x> struct x { typedef x* type; };
f()(x)				==>		f::apply<x>::type
a[x]				==>		mpl::at<a, x>::type
(x ? y : z)			==>		mpl::if_<x, y, z>::type
switch (if_<x, y, z>)		==>		*Уфф*, общая (default) и частичные специализации
{
	case if_<bool_<false>, y, z>: return y;
	default: return z;
}

Под хабракатом есть немного пояснений :)
Читать дальше →
Total votes 27: ↑22 and ↓5+17
Comments14

Ленивые вычисления в с++0x, тест новых фич

Reading time1 min
Views4.7K
Всем привет. А особенно тем, кто пишет на плюсах и интересуется грядущими изменениями языка.
Для исследования фич нового стандарта С++ я сделал забавную штуку — функцию для превращения простого функтора в ленивый. Т.е. вычисляемый не более одного раза, и только при первом обращении.
Для использования вам понадобится простой функтор, без аргументов, возвращающий значение.
Применяете к нему calc_once(some_func) — и он становится ленивым.

auto my_func = calc_once([]{ return SomeHugeCalculation(); });
if ((my_func() && some_case) || (!my_func() && some_other_case))
{
}


* This source code was highlighted with Source Code Highlighter.


Под хабракатом код, там и auto, и decltype, и лямбды.

UPD. Спасибо за карму. Перенес в блог С++.

Читать дальше →
Total votes 39: ↑34 and ↓5+29
Comments29

Information

Rating
Does not participate
Location
Новосибирск, Новосибирская обл., Россия
Date of birth
Registered
Activity