C++0x наконец-то вышел. Кто-то безгранично рад этому и уже по полной использует его новые возможности, кому-то все равно, ну а кто-то не видит в этом ничего хорошего. Что касается меня, то я отношусь к нему с осторожностью, изучая его и пытаясь найти рациональное применение новым особенностям языка.
Вчера я смотрел доклад Герба Саттера на конференции Going Native 2012, где он рассказывал о С++11 и о том, как он меняет способ использования С++. Рассказывая о ключевом слове auto, Герб призвал использовать его по умолчанию, явно указывая тип только когда это необходимо. Бесспорно, использование auto сильно упрощает набор олимпиадного кода. Например,
map<string, pair<int, int> > m;
auto i = m.find("a");
писать гораздо проще, чем "по-старому".
Однако в больших проектах, как мне кажется, ситуация иная. В таких программах огромное значение имеет читабельность кода, простота его восприятия, а не сокращение времени его набора. Рассмотрим пример.
auto x = foo(Widget());
x.bar();
Что можно сказать, взглянув на этот код? Очевидно, функция foo()
возвращает объект некоторого класса, у которого потом вызывается метод bar()
. Для дальнейшего использования объекта x мы должны знать его класс, чтобы обращаться к его интерфейсу. Как узнать этот класс?
Ответ напрашивается сам собой — посмотреть объявление функции foo()
. Любая современная IDE подскажет вам тип возвращаемого ею значения, вам даже не придётся искать её в проекте. Однако это требует выполнения дополнительного действия, в котором не было бы необходимости при явном указании типа. К тому же, стоит отметь, что возникает зависимость от IDE, с бумажки такой код читать будет тяжелее. Пусть это и не столь критично, но всё-таки...
А ведь ситуация может оказаться ещё веселее. Рассмотрим вот такой код:
auto foo(Widget w) -> decltype(w.prop())
{
return w.prop();
}
Что мы здесь видим? Тип функции foo()
нигде явно не определён, необходимо узнать, что возвращает метод prop()
класса Widget
. А это требует дальнейшего исследования кода. В результате мы можем уйти глубоко в дебри нашего проекта, только чтобы узнать, какой тип имеет переменная x. Конечно, приведённые примеры искусственные, но мне кажется, нечто подобное запросто может появиться и в реальном коде.
Резюме. Этой статьёй я не хочу сказать, что C++11 — это плохо, и его использование не принесёт ничего кроме дополнительной головной боли. Я только хочу сказать, что использовать его возможности надо умеренно и только там, где они действительно упрощают создание и понимание кода. auto, на мой взгляд, — это очень полезная возможность C++11, однако его чрезмерное употребление может существенно усложнить понимание написанного кода. Поэтому я не согласен с Саттером и считаю, что использование auto по умолчанию — не очень хорошая идея.