Pull to refresh

C++11 — removed and deprecated

Reading time 3 min
Views 15K

Все уже в курсе выхода нового стандарта С++11, на Хабре уже было несколько статей о его фичах. А я вот решила написать о том, что из С++ в новой версии было исключено и по каким причинам. Оно, может быть, кажется и не таким важным, как новые возможности, но, как говорится: «Тот, кто не знает истории, обречён на повторение ошибок».

Dynamic exception specifications


Вы, наверное, знаете, что при объявлении функций можно указать, какие типы исключений эта функция будет генерировать. Ну вот как-то так:
int A() throw(); // не может генерировать исключений
int B() throw(A,B); // может генерировать A или B
int С(); // может генерировать любые исключения

И казалось бы — всё хорошо, вот только на самом деле:
  1. Функция А может сгенерировать любое исключение
  2. Функция B может сгенерировать любое исключение
  3. Функция С может и вовсе ничего не сгенерировать.
Кому интересно, почему так — может почитать вот эту статью. Я уже молчу о том, что синтаксис функции А абсолютно неинтуитивен — я когда впервые его увидела, решила, что как раз функция A может генерировать любые исключения, а С — никаких. Кроме того, некоторым компиляторам (например, Microsoft Visual C++) на объявления в стиле функции B глубоко плевать — никаких проверок выполнятся не будет, о чём честно предупредит warning.

Теперь вся эта чехарда убрана и добавлено одно ключевое слово «noexcept», объясняющее, что функция генерировать исключения не может. И всё.

auto_ptr


Один из видов умных указателей более не будет радовать нас своим присутствием в С++. auto_ptr убран. Задумка auto_ptr была хорошей, вот только на практике оказалось, что люди абсолютно не читают документацию. И хотя на счёт auto_ptr чётко сказано, что его нельзя использовать, например, с STL-коллекциями, все постоянно это делали. А самое плохое, что это приводило к неопределённым результатам. Например, вот такой вот код:
vector<auto_ptr<int> > vi;
//..populate vi
sort(vi.begin(), vi.end(), indirect_less());

В зависимости от компилятора, ОС, версии STL и фазы луны может работать, не работать или даже вовсе падать. Комитет по стандартизации С++ отчаялся взывать к разуму и заменил auto_ptr на unique_ptr, который в проблемных для auto_ptr случаях ведёт себя вполне определённым образом: либо работает, либо не компилируется. Я думаю, все согласятся, что это значительно более предпочтительное поведение.

Понятие «точка следования»


О точках следования всегда любили со знанием дела рассуждать любители вопросов «а сколько будет i++ + ++i ?». Ранее стандарт С++ определял, какие операции являются точками следования, а какие нет. Теперь понятие упразднено, хотя по сути ничего не изменилось. Все операции всё-равно делятся на гарантирующие последовательность выполнения определённых действий и не гаранитирующие. Теперь говорят просто «операция последовательна» или «операция не последовательна». Объясняется это изменение какими-то призрачными надеждами на упрощение стандартизации новой модели памяти (о чём вообще идёт речь?) и т.д. Мне кажется — вранье. Просто «точка следования» звучало как-то сильно сложно. :)

Экспорт шаблонов


Я думаю, мало кто знал или использовал эту фичу. Вот пример:
// File 1:
#include <stdio.h>

static void trace() { printf("File 1\n"); }

// declaration only
export template <class T> T const& min(T const&, T const&);

int main() {
  trace();
  return min(2, 3);
}

// File 2:
#include <stdio.h>

static void trace() { printf("File 2\n"); }

//The definition
export template <class T> T const& min(T const &a, T const &b) {
  trace();
  return a<b ? a : b;
} 

Обратите внимание — в одном файле объявляется шаблонная функция, в другом — реализуется, при этом файлы не включают друг друга и каждый имеет собственную версию функции trace(). Больше по этой теме можно почитать тут. Компания Edison Design Group много лет назад настояла на добавлении этой возможности в стандарт. Им она казалась очень важной, они даже сделали реализацию в собственном компиляторе, правда, кроме них этого не сделал больше никто (хотя их разработку, использовала, например, Borland). Прошло время и EDG признали, что ошиблись. Из стандарта С++11 экспорт шаблонов убрали.

Удачи всем в изучении нового стандарта, буду очень рада, если статья окажется для кого-то полезной.
Tags:
Hubs:
+172
Comments 46
Comments Comments 46

Articles