Просмотрел повнимательнее список новшеств в будущем стандарте C++0x и обнаружил, что многие грабли, которые приходилось раньше реализовывать самостоятельно или городить воркэраунды, теперь будут поддерживаться конструкциями языка или добавлены в стандартную библиотеку. Это не может не радовать, потому что это сильно облегчает жизнь.
- Первым пунктом у меня идут потоки и объекты синхронизации (§30 [thread]):
thread
,mutex
,lock
,condition_variable
,future
, ... Наконец-то! Надеюсь, теперь можно будет выкинуть весь самописный код, который реализовывал классы с подобной функциональностью для использования на различных платформах. Конечно, было бы неплохо расширить список поддерживаемых Стандартом объектов синхронизации, но и существующий список вполне хорош. static_assert
— проверка условий на этапе компиляции, которой так не хватало в предыдущих версиях Стандарта. Очень полезна для проверки размеров типов данных и кратности этих типов каким-то заданным значениям. (§7 [dcl.dcl])- Списки инициализации и универсальная инициализация — новая синтаксическая конструкция (§8.5.4 [dcl.init.list]), которая позволяет инициализировать массивы, структуры данных и контейнеры следующим образом:
double ad[] = { 1, 2.0 };
S2 s22 { 1.0, 2, 3 };
std::map<std::string, int> anim =
{ {"bear",4}, {"cassowary",2}, {"tiger",7} };
shared_ptr
— умные указатели (§20.9.11 [util.smartptr]). Объект, хранимый умным указателем, уничтожается только после того, как счетчик ссылок на объект будет равен нулю.- Лямбда-выражения (§5.1.2 [expr.prim.lambda]). К самим по себе лямбда-выражениям я отношусь достаточно спокойно. Даже, пожалуй, скептически, потому что мне кажется, что фанатичное использование лямбда-выражений приведёт к хаосу (особенно выражений, которые изменяют состояние классов). Но у лямбда-выражений есть свойство, которого мне раньше не хватало — их можно передавать в классы и алгоритмы стандартной библиотеки (и в пользовательские шаблоны) в качестве предикатов. Раньше надо было городить кучу кода, определяя дополнительные функции и классы, причем передавать в шаблон локальный класс запрещено. А с новым стандартом можно сделать так:
std::sort(x, x + N,
[](float a, float b)
{ return std::abs(a) < std::abs(b); });
- Автоматический тип данных
auto
— тип объявляемой переменной определяется самостоятельно из типа инициализатора. Особенно удобно использовать при работе с итераторами контейнеров и другими типами, от которых зависит шаблон, чтобы не париться с горой typedef'ов. (§7.1.6.4 [dcl.spec.auto]) - Возможность вызова конструкторов класса из других конструкторов этого же класса (§12.6.2 [class.base.init]). Очень сильно облегчает написание конструкторов классов, помогает избежать дублирования кода инициализации.
- Цикл
for
по коллекциям (§6.5.4 [stmt.ranged]). Не очень актуально, учитывая появлениеauto
и лямбда-выражений, но объём кода уменьшает.
int array[5] = { 1, 2, 3, 4, 5 };
for (int& x : array)
x *= 2;
- Из маленьких приятных мелочей можно упомянуть поддержку генераторов случайных чисел (§26.5 [rand]), атомарных операций (§29 [atomics]), регулярных выражений (§28 [re]) и новых алгоритмов. Например, алгоритм
iota
(§27.6.5 [numeric.iota]), который заполняет заданный интервал инкрементирующимися значениями, начиная с заданного (подобный функционал я реализовывал с помощью алгоритма generate и самописного класса UniqueNumberGenerator).