СтатьиВведение в C++11: auto, decltype, nested templates и range-based-for

На других языках: English

Этим постом я хочу открыть серию публикаций на тему нововведений в долгожданном недавно принятом стандарте — C++11. Ниже я рассмотрю самые известные и самые простые нововведения, но с каждым постом буду погружаться все глубже и глубже.

Декларация типа с помощью auto

Углубляясь в историю, стоит отметить, что auto переменные были и раньше, до принятия стандарта C++11. Вот только значение они имели другое. Под auto подразумевался спецификатор хранения переменной. То есть, auto находился в одном ряду с register, static, extern, и указывал на то, что переменная имеет локальное время жизни. Об этом почти не знают начинающие, так как любая переменная объявленная в некотором блоке неявно определяется как auto.

Например, следующие два объявления абсолютно идентичны:

void foo()
{
    auto int x = 0;  // явно указывается `auto`
    int y = 0;       // не явно указывается `auto`
}

Стандарт C++11 принес более полезное значение этому ключевому слову. Теперь auto позволяет не указывать тип переменной явно. За определение типа отвечает компилятор, который вычисляет его на основе типа инициализируемого значения.

void foo()
{
    auto x = 5;  // тип переменной x будет int
    x = "foo";   // ошибка! не соответствие типов

    auto y = 4, z = 3.14; // ошибка! нельзя объявлять переменные разных типов
}

Введение auto ужасно повышает читабельность кода, так как теперь нет необходимости писать длинные шаблонные типы. Например, при получении итератора:

// c++03 решение
for (std::vector<std::map<int, std::string>>::const_iterator it = container.begin();
     it != container.end();
     ++it)
{
    // do something
}

// c++11 решение
for (auto it = container.begin(); it != container.end(); ++it)
{
    // do something
}

Что такое decltype и с чем его едят?

decltype позволяет статически определить тип по типу другой переменной.

int x = 5;
double y = 5.1;

decltype(x) foo;    // int
decltype(y) bar;    // double

decltype(x+y) baz;  // double

Обратите внимание на последнюю строчку. Тип можно определить даже на основе математических операций между переменными. Это очень мощное и полезное средство при написании шаблонных функций, когда необходимо указать возвращаемый тип. Однако, в этом случае код выглядит не так просто, как хотелось бы.

template<class T, class U>
    auto hellSum(const T& x, const U& y) -> decltype(x + y)
    {
        return x + y;
    }

Это лишь пример, и реально в decltype можно использовать результаты функций, функторов и т.д.

">>" как закрытие вложенных шаблонов

Со времен первого стандарта существовала проблема с закрытием сложных шаблонных типов. Её суть заключалась в том, что нельзя было ставить два знака > вместе. Наверное это связано с тем, что когда-то, писать более умный парсер, отличающий >> в зависимости от контекста (>> является, также, сдвигом вправо), было сложно. К тому же, такая проверка, возможно, была дорогостоящей.

Так или иначе, было справедливо следующее:

std::vector<std::map<int, int>> foo;    // ошибка компиляции
std::vector<std::map<int, int> > foo;   // вполне корректный код

Но с принятием C++11, первый вариант стал тоже корректным и допустимым.

Range-Based for

Range-Based for — это цикл по контейнеру. Он аналогичен циклу for each в Java или C#. Синтаксически он повторяет for each из Java. Назван он Range-Based в первую очередь потому, чтобы избежать путаницы, ибо в STL уже давно есть алгоритм, именуемый std::for_each.

std::vector<int> foo;

// заполняем вектор

for (int x : foo)
    std::cout << x << std::endl;

Модель ссылок работает также, как и везде:

for (int& x : foo)
    x *= 2;

for (const int& x : foo)
    std::cout << x << std::endl;

Красиво и удобно, правда? Рассмотренный выше auto усиливает данную конструкцию:

std::vector<std::pair<int, std::string>> container;

// ...

for (const auto& i : container)
    std::cout << i.second << std::endl;

Стоит отметить, что хоть range-based for и является мощным и удобным инструментом, он, как и все остальное в C++, не работает на Святом Духе, как могут считать некоторые представители педагогического состава нашей страны. range-based for неявно вызывает у контейнера методы begin() и end(), которые возвращают, в свою очередь, привычные нам итераторы.

Range-Based for, к слову, работает и на обычных статических массивах:

int foo[] = {1, 4, 6, 7, 8};

for (int x : foo)
    std::cout << x << std::endl;

Вместо заключения

Выше я привел лишь малую толику нововведений C++11. Вкусностей гораздо больше, и вы о них узнаете, оставаясь подписчиком моего блога! :)

Комментарии (30):
@malor

С принятием нового стандарта писать на С++ станет приятнее)). Жаль только, что вся эта бюрократия со стандартными занимает столько времени - в Python это был бы point release...

> ответить
@ikalnitsky

@malor, не равняй python с божественными плюсами! ;)

Но вообще ты прав. :( Комитет дико тормозит.

> ответить
@Miks

Одно плохо C++ становиться все больше уделом избранных, сейчас большинство выбирают путь попроще, где к ко всему можно, относиться спустя рукава. Правда и кодиться все намного быстрей. Видим маленькие шаги по упрощению в этом 11 стандарте, но нужно быть более гибкими иначе время потерют безвозвратно.

> ответить
@uktop40

нововведение с auto порадовало :)

> ответить
@Zoresvit

@Miks, ну а кто сказал, что это плохо? Зависит от применения, конечно. Друг учится на прикладной лингвистике и там частенько нужно написать какие-то алгоритмы, иногда сложные, иногда не очень. Только в самом университете бахнутые на голову профессора читают Delphi, а на самом деле им в идеале Python бы читать или что-то функциональное. Им им нафиг не нужно знать все эзотерические нюансы функционирования языка — не нагруженные системы ведь программируют :) Так что упрощение — это хорошо. Только действительно плохо, что такой latency.

> ответить
@АнтонК

Не знал, что стандарт C++ продолжают допиливать. Нововведения, конечно, радуют, и народ оценит... Впрочем сейчас мало коммерческих проектов стартуют на C++. В основной массе C++ остался в дремучих проектах с корнями, и нововведения им вряд ли помогут.

> ответить
@ikalnitsky

@АнтонК, а на чем стартуют коммерческие проекты? :) На C#? На Java? Я бы не так сказал. C# и Java перебрался в корпоративный сектор -- программы на заказ, разработка ПО под собственные нужды. При этом, написание именно коммерческого проекта (в плане, что ПО будет продоаваться за деньги) все же идет на С++. Почему? Потому, что это, как правило, крупные проекты, скорость выполнения которых крайне важна.

А если брать в общем, то коммерческое ПО пишется в основном на Objective-C и Java, в следствии популяризации мобильных платформ. Под десктопы уже очень много бесплатного софта. :)

> ответить
@Alex

А у Русских минталитет такой что все бесплатно =) И вы бредите! Откуда вам знать на чем стартуют комерческие проекты? Каждый проект требует свои технологии! И выбор среды разработки и языка на котором будет стартовать проект зависит не от того комерческий или нет, а от того какие цели он приследует!

> ответить
@ikalnitsky
Каждый проект требует свои технологии! И выбор среды разработки и языка на котором > будет стартовать проект зависит не от того комерческий или нет, а от того какие цели он приследует!

Верно. Но я уже выше отмечал, что каждый успешный коммерческий проект -- это критические к выполнению системы. А на чем их писать, если не на C++? :)

> ответить
@Ильич

Может хватит уже себя утешать C++ сники ? Если вы и вправду не согласны что C++ используют в полной мере только крупные корпорации у которых движки уже имеют десятилетний этап разработки и у которых C++ код уже просто нет смысла менять, так как там уже всё итак работает, и вы и впрям считаете что таким корпорациям будет толк от подобных нововведений, ради которых придется переписывать весь код, то вы живете в мире грез и фантазий.

Поэтому скажем EA, Blizzard, Epic и прочим эти улучшения нафиг не нужны. У них уже есть абсолютно все велосипеды и костыли для C++ которые им нужны в работе для внутреннего пользования, и менять они врядли что то будут.

> ответить
@ikalnitsky
Может хватит уже себя утешать C++ сники ? Если вы и вправду не согласны что C++ используют в полной мере только крупные корпорации у которых движки уже имеют десятилетний этап разработки и у которых C++ код уже просто нет смысла менять, так как там уже всё итак работает, и вы и впрям считаете что таким корпорациям будет толк от подобных нововведений, ради которых придется переписывать весь код, то вы живете в мире грез и фантазий.

Господи, какой наивный взгляд. Скажите, а какие есть альтернативы? Не будем рассматривать мир *nix, где большинство софта написанно на C, C++ и Paython, где на Java написан шлак, а C# не используется почти воощбще (кроме некоторых Mono проектов).

Возьмем распространенный Windows.Какуй ситуацию вы видем? Java — шлак, софт на нем не пишется вообще. Java — это сейчас Android, да и поддержка старого говна в секции enterprise. В эпоху Win7 миром виндой правит C#, как для прикладного ПО, так и для asp'шных enterprise приложений.

Ну что мы имеем? Что Java, что C# — сосут в производительности. Покажите мне драйвера на C#/Java? Покажите мне игрулины, на C#/Java? Говорить, что у таких компаний как Blizzard/etc все написано на C++ и поэтому они его поддерживают — очень тупо. Как по вашему делаются новые игры? На старых движках? Абсурд! Нельзя что-то тянуть долго, ибо рано или поздно будет предел. Это ниша C++. Про embed системы я вообще молчу — все они на C/C++, никаких джав и си шлаков.

Взглянем на шаг вперед? Windows 8 со знаменитым Metro. Теперь писать можно на Html/js, более того, это является реккомендуемым. Где остается C#? Ниша прикладного ПО отсеивается, остается enterprise. Да и там, не все так гладко. Использовать C# или Java — это прошлый век, сейчас еть намного более удобный и более гибкий Python.

Что мы видим с C++? Он жил, живет и пока что будет жить. Еще нет языка, который бы успешно заменил его. К тому же, даже Microsoft (которая, по идеи, должна пропагандировать C#) разрабатывает C++ amp — бибилотеку для вычислений на графических процессорах.

Вывод: языки приходят и уходят, а С++ жив и нет никаких предпосылок ему умирать.

p.s: а если бы пользователь винды раскрыли глаза и увидели бы Qt, они бы (если им позволили мозги) заметили бы, что во многих аспектах удобней, чем .NET.

> ответить
@Fl0

Ну на C# из игрушек Magicka есть. Тормозить любит... А qt далеко не панацея, и вообще в старых версиях течь любил.

сейчас пользуюсь связкой C++ + boost + qt/gtk + cmake + удобная ide

> ответить
@ikalnitsky
А qt далеко не панацея, и вообще в старых версиях течь любил.

Да, не панацея, но очень удобный и мощный инструмент, который позволяет уравновесить по простоте использования C++ и, например, тот же C#. :)

> ответить
@just@man

@ikalnitsky, Полностью согласен, а по поводу Qt добавлю, что это именно то, чего так не хватает плюсам. C#, Java в основном просты в использовании именно из-за своего удобного библиотечного окружения, оно у них стандартное и ничего дополнительно тянуть не нужно. Но C++ повезло меньше в силу его универсальности, но тут Qt полностью закрывает эту дыру, он даёт языку необходимое библиотечное окружение. Написать проект на C++ + Qt ничем не тяжелее чем на том же C# или Java. Те кто фанатеет от .Net рабы рекламы, мелкософт везде пытается засунуть свой нос и впарить свой продукт. Программите под .Net? Поздравляю! Вы успешно купились на рекламную компанию от фирмы Microsoft! Microsoft делает бизнес и всегда его делала. А плюсы, которые никто не рекламирует всё равно используются и будут использоваться и никуда они не денутся ... Новичков пугает мощь языка, которую им не под силу осилить, но ещё больше их пугает что плюсы обычно преподносятся на одном подносе с таким говном как MFC или тем же WinAPI, будто бы альтернатив до сих пор нету ... Единственный минус C++ - это тугой комитет, который уж больно неповоротлив ... Радует, что они уже наконец осилили новый стандарт ... И новые возможности очень радуют, люди, для которых программирование - это искусство, которые творят, а не работают по одним лишь шаблонам, по достоинству оценят нововведения. Конечно некоторые из них уже давненько присутствуют в конкурирующих языках, но в них отсутствуют многие полезные возможности плюсов, которые совместно позволяют творить на совершенно ином уровне ... Обидно, что программисты вместо того чтоб совершенствоваться всё больше и больше деградируют, всё больше теряется контроль над программой. Всем известный сборщик мусора ассоциируется у меня с нянькой, которая подтирает попу ребёнку, потому что он сам не в состоянии это сделать и не знает когда это вообще нужно делать ... Множественное наследование - это зло??? Это гемор для разработчиков компиляторов, новички могут запутаться в нём ... Выход? Убрать нафиг ... Снова упрощение ... Вам отрезают руки и ноги, а Вы им аплодируете! Ну да, нам же взамен дали довольно удобные костыли ...

> ответить
@ikalnitsky
C#, Java в основном просты в использовании именно из-за своего удобного библиотечного окружения, оно у них стандартное и ничего дополнительно тянуть не нужно. Но C++ повезло меньше в силу его универсальности...

Ну тут сложно сказать: "повезло больше или меньше". C++ просто затачивается под другие дела. Добавлять вещи, которые не всегда можно эффективно реализовать -- не есть философия C++.Поэтому включения Qt в стандартную библиотеку -- не панацея. На данный момент C++ применяется чаще там, где бы тот же Qt однозначно не использовался.

Другое дело, что разработчикам компиляторов и сред программирования было бы неплохо включать Qt как third-party библиотеку, которую можно ставить по желанию. Это бы, на мой взгляд, популяризовало бы Qt и повлияло бы на мнение новичков о C++ в целом. Во всяком случае, у них не складывалось ложное мнение, что C++ -- это WinApi и MFC. :)

Программите под .Net? Поздравляю! Вы успешно купились на рекламную компанию от фирмы Microsoft!

У меня такое внутренне ощущение, что MS уже сделали ставку на JS-приложения, и .net отойдет на второй план (останется пока как enterprise решение).

Единственный минус C++ - это тугой комитет, который уж больно неповоротлив ..

О, да. Я очень переживаю по этому поводу. Не хочу чтобы C++ разделил судьбу OpenGL: когда технология перспективная, а из-за нерасторопности комитета сторонние технологии обходят.

Всем известный сборщик мусора ассоциируется у меня с нянькой, которая подтирает попу ребёнку, потому что он сам не в состоянии это сделать и не знает когда это вообще нужно делать ...

Да, новое поколение разочаровывает. Они не то, что не знают когда ресурсы очищать, и как вообще ресурсы выделяются системой. Они вообще мало чего смыслят в работе ОС. А это, имхо, важный фактор для хорошего программирования. Я постоянно вижу, как программисты на Java/C# создают по 100500 потоков, мол, так быстрее. =О времени на создание контекста потока, о времени затрачиваемом на переключение -- они, разумеется, не слышали.

Кстати, по поводу Garbage Collector. У Страуструпа есть хорошая цитата по поводу его необходимости в C++.

> ответить
@just@man

@ikalnitsky, Я не имел ввиду, что Qt необходимо сделать стандартной библиотекой, такого никогда в жизни не будет, да оно и не нужно. Я лишь хотел сказать, что Qt позволяет с лёгкостью использовать C++ в тех местах, где используются управляемые языки. Qt даёт нам удобную и красивую среду, избавляет от необходимости использовать родные интерфейсы операционки, которые за частую не очень то удобны в использовании. Но я полностью согласен, что C++ часто используется и там, где Qt нету места. На то он и универсальный язык общего назначения.

По поводу JS и MS, есть конечно в этом что-то, но серьёзных приложений так не напишешь. Это годится для простеньких десктоп приложений, где производительность не имеет никакого значения ... Это, конечно, только моё мнение ...

У OpenGL комитет ещё довольно шустрый, если сравнивать с С++-вым. На сколько я знаю, последняя версия OpenGL не уступает по возможностям DirectX-у (Direct3D). Правда уже достаточно долгое время OpenGL догоняет Direct3D, а не наоборот (что имело место быть в прошлом) и делает он это довольно шустро. У меня была идея заняться геймдевом (уж больно перспективная область), но сейчас есть другие приоритеты. Но если я всё таки надумаю этим заняться, то предпочту OpenGL DirectX-у. Конечно движок должен уметь работать и с другими программными интерфейсами, дабы поддерживать мир консолей. И тут смущает только одно - неразрушимая связь Xbox-а с DirectX-ом. Ну что тут поделаешь, у Microsoft-а всё своё, "домашнее". Зачем им открытые стандарты, когда можно придумать свою технологию и держать людей на коротком поводке ... Ориентируясь на один только OpenGL можно писать приложения и игры для винды, линухов, маков, Playstation (думаю, если покопаться, то список можно расширить), а в мобильном мире OpenGL вообще рулит! Когда уже люди перестанут поддерживать монопольную политику мелкософта и перейдут на открытые технологии ... Боюсь ещё не скоро ...

> ответить
@CsharpMan

А я вот даже рад, что комитет у С++ "тормозной" :-) Тише едешь - дальше будешь. В стандарт должны входить только действительно нужные и проверенные временем вещи. Не надо делать из С++ гору синтаксического сахара как в С#. Стандарт должен "устаканиться", все подводные камни, все плюсы и минусы должны провериться временем. Не нужно на каждый чих и мимолетное желание "подсластить" код - выпускать по новому стандарту/фреймворку/технологии. Хотите сладкой жизни - берите питон, руби или лисп.

Насчет вообще дотнета: в конторе, где я работаю, мы пишем промышленные SCADA-системы, на шарпе, черт бы его побрал. По началу все эти плюшки в виде удобной студии для клепания интерфейса, сборщик мусорв и тонны сахара очень даже радовали и вселяли уверенность в правильности выбора. Но через несколько лет туман экстаза рассеялся. Система становилась больше, требования все росли, и, по началу, так любимый сборщик мусора стал создавать больше проблем, чем давал помощи. Пришло время жесткой оптимизации и тут все завертелось - все эти бесконечные unsafe-блоки, маршинг в нативные структуры и обратно... вообщем без мата и не скажешь. Кто-то скажет что это неправильный выбор инструмента, и возможно будет прав, но как тут уже говорили - майкрософт ведет хорошую пиар компанию, и очень часто руководство фирм к ним прислушивается, ведь как можно не полюбить "высокопроизводительный управляемый язык, дающий скорость С++ и убирающие все его недостатки". И как только вы потратите несколько лет на изучение одной из их технологий (.net,silverligth,wpf,xna,com,activx,dde и т.п.) они выкотят нагора новую, "улучшенную" технологию и снова заставят вас плясать под свою дудку. А С++ и другие открытые технологии как жили, так и живут себе, меняясь постепенно, под воздействием реальных требований жизни, а не желания маркетологов. Извиняйте за эмоции :-)

> ответить
@ikalnitsky

@CsharpMan, да никто и не говорит, что надо добавлять синтаксический сахар, фреймворки и технологии. Просто есть вещи, которые весьма часто нужны в повседневном программировании и было бы неплохо все же добавить их в стандарт, чтоб не пришлось каждый раз городить велосипеды.

К таким вещам я отношу regexp'ы (которые наконец добавили в стандарт), xml/json парсеры и работу с сетью. Я считаю, что наличие этих вещей в стандарте позволит писать более кроссплатформенный код и избавит человека от выбора сторонней библиотеки. При этом да, добавлять кучу таких useful тулсов — не панацея; не надо из плюсов делать java. Просто расширить стандартную библиотеку все же не помешало бы. :)

> ответить
@CsharpMan

@ikalnitsky, ну за ввод новых фишек через стандартную либу - я только за :-) Главное не вносить часто изменения и в без того достаточной сложный язык (хотя auto и лямбды только упрощают С++). Эх как я ждал модулей в новом стандарте, эта долгая компиляция достает:-) Вчера скачал язык D со студией и офигел от скорости компиляции.

> ответить
@ikalnitsky
@ikalnitsky, ну за ввод новых фишек через стандартную либу - я только за :-) Главное не вносить часто изменения и в без того достаточной сложный язык

Безусловно. Вносить надо то, что меняться уже не будет (за исключением некоторых минорных изменений, e.g. добавление метода). Уже ведь существует достаточно много открытых проектов, которые так или иначе своим апи напоминают стандартную библиотеку. Можно же взять это за основу и ввести в стандарт? Так ведь поступили с shared_ptr и regexp, например, и все пользователи только рады. :)

auto и лямбды только упрощают С++

Да, это сахар. Но сахар весьма полезный. Лямбды еще больше приближают нас к функциональному стилю и позволяют код сделать более понятным и наглядным (не приходится рыскать в поисках используемого функтора). А auto просто приятная мелочь, которая позволяет на заморачиваться с выведением сложных типов вручную.

Эх как я ждал модулей в новом стандарте, эта долгая компиляция достает:-) Вчера скачал язык D со студией и офигел от скорости компиляции.

Что значит модулей? В C++ есть такое понятие как единица трансляции. Современные системы сборки проектов не перекомпилируют единицы трансляции, если в них не было изменений. Поэтому, по идеи, с технологической точки зрения скорость компиляции достаточно высока (опять же, если юзать make, vs и прочие системы сборки). Может скорость компиляции D уже зависит от самого компилятора D, а не от модулей?

> ответить
@CsharpMan

@ikalnitsky, ты прав,скорость компиляции прежде всего зависит от языка, у С++ достаточно сложный синтаксис, контекстнозависимая грамматика. Ну и плюс еденица трансляции - файл,(а хотелось бы модуль, как например в паскалях или шарпе), что негативно сказывается на скорости компиляции. Конечно существуют прекомпилируемые хедеры - но это не по стандарту. Вообще про низкую скорость компиляции С++ можно вот тут прочитать (пишет разработчик компиляторов)

Сейчас мой рабочий проект на шарпе (около сотни тысяч строк)пересобирается буквально за 5 секунд, а к примеру небольшие утилиты на С++/Qt на тысячу строк компилятся столько же, а то и дольше. Понимаю что сравниваю разные вещи, но все-таки хотелось бы быстрее :-)

> ответить
@ikalnitsky
Ну и плюс еденица трансляции - файл,(а хотелось бы модуль, как например в паскалях или шарпе)

Прошу прощения, но я не могу понять: что не так? В чем разница? Разве модуль это не файл? Да и какая вообще разница для программиста, что представляет собой единица трансляции? :)

Вообще про низкую скорость компиляции С++ можно вот тут прочитать (пишет разработчик компиляторов)

Ну все не так плохо, как пишет этот "некто". Во-первых, он упоминает о страже включения через #ifndef. Мол, если хедер включится в другом модуле (хотя раньше он уже был включен и, следовательно, сейчас повторное включение не обязательно), то он будет препроцессором обрабатываться вновь. Да, все так. Но стандарт не требует этого, и, возмонжо, современные компиляторы умеют это обходить. К тому же не следует забывать о #pragma once, который поддерживается всеми популярными компиляторами и призван как раз для ускорения этой фазы (которая в больших проектах как раз и занимают громадную долю времени).

Во-вторых, проблема в том, что люди не знаю о такой вещи как forward declaration, и фигачат #include во всех хедерах без разбору, в следствии чего из-за перекрестного препроцессинга и происходит замедление.

Сейчас мой рабочий проект на шарпе (около сотни тысяч строк) пересобирается буквально за 5 секунд, а к примеру небольшие утилиты на С++/Qt на тысячу строк компилятся столько же, а то и дольше. Понимаю что сравниваю разные вещи, но все-таки хотелось бы быстрее :-)

Да ну не может быть такой разброс. Если в C++ писать все по стайлу (с pragma once и forward declarations) — то время сборки не должно так сильно отличаться. Можно еще поковырять настройки компиляторов, возможно там есть опции отключающие определенные стадии (e.g. триграфы).

p.s: в C++/Qt проектах проблема еще в том, что исходники проходят процедуру moc обработки, а это занимает длительное время.

> ответить
@CsharpMan

@ikalnitsky, этот "некто" Уолтер Брайт -программист, известный как главный разработчик первого «родного» компилятора C++ Zortech C++ (позже ставшего Symantec C++, а затем Digital Mars C++) и создатель языка D. Хотя, ты конечно прав, если все правильно настроить - жить можно, это я так, придираюсь:-) Хотя есть слабое место, которое никакими настройками не исправить - шаблоны, даже на современных машинах шаблоны в духе Александреску - компилироваться могут десятки минут.

> ответить
@ikalnitsky
Хотя есть слабое место, которое никакими настройками не исправить - шаблоны, даже на современных машинах шаблоны в духе Александреску - компилироваться могут десятки минут.

Ну у шаблонов C++ есть одна особенность — они compile-time. Т.е., значения вычисляются на этапе компиляции. Поэтому, разумеется, это занимает определенное время. Но ведь подобного механизма нет ни в Java ни в C# (ибо generics — это не шаблоны). Поэтому сравнивать эту составляющую с ними нельзя (как дело обстоит с D — не знаю). :)

> ответить
@CsharpMan

@ikalnitsky, Ок, С++ обсудили с ног до головы :-) Можно вопрос не по теме, раз мы уж здесь начали бурные дебаты. Я вот много и очень много восторженных отзывов слышал о питоне, решил расширить кругозор (мои рабочие языки С# и С++). Купил книгу по питону, прочел, выполнил почти все задания, написал пару не сложных программулин, и вот что-то вообще не увидел ничего такого, о чем так хвалебно рассказывают. "Язык сверхвысокого уровня", "программирование со скоростью мысли" и т.д. Неужели людей правда так привлекает отделять блоки отступами или они считают что срезы, кортежи, списки и объявления переменных без типа - это большие преимущества питона? В плюс можно поставить только REPL, но для меня это несущественно. Просто у тебя вроде блог на джанго, решил спросить:-)

> ответить
@ikalnitsky
Неужели людей правда так привлекает отделять блоки отступами

Ну нет, конечно. :) Не это самое главное в языке. На мой взгляд это лишь средство, которое заставит людей более красивее форматировать код и только.

или они считают что срезы, кортежи, списки и объявления переменных без типа - это большие преимущества питона?

А вот это уже да. Динамическая типизация — это большой плюс, который облегчает программирование. К тому же, декларативное объявление тоже является плюсом.

lst = [1, 4, 8, 10]

Вместо того, что в C++:

#include <vector>

// в C++03
std::vector<int> lst;
lst.push_back(1);
lst.push_back(4);
lst.push_back(8);
lst.push_back(10);

// в c++11
std::vector<int> lst = {1, 4, 8, 10};

Да, конечно, в C++11 был сделан шаг вперед. Но все же, подключение вектора, более длинная форма записи говорят не в пользу C++. Но по правде говоря, меня больше прельщает в Python'е то, что в нем есть фичи из функционального мира:

  • filter
  • map
  • list/set/map comprehensions
  • lambda (хотя в C++11 они тоже введены)

Ну а также:

  • мего-удобные и полезные декораторы
  • гибкость при создании классов оберток (__getattr__)
  • всё в python является объектом
  • динамическое добавление атрибутов конкретным объектам
  • широкая стандартная библиотека
  • много third-party библиотек

Ну и отдельно хочется сказать о Django. Этот фреймворк действительно очень упрощает жизнь в веб-программировании и позволяет писать код красиво.

Увы, нельзя легко и просто выразить все эмоции. К этому можно только прийти. Поэтому я для себя выбрал два основных языка: c++ и python :)

> ответить
@Csharpman

@ikalnitsky, спасибо за развернутый ответ:-) Мои мысли по пунктам:

  1. Красиво форматировать код в наше время не проблема, например Visual Studio делает это сама, но не заставляет.
  2. Динамическая типизация - перенос ошибок которые можно отловить при компиляции- в рантайм. Да и мне статика кажется удобнее, ИМХО конечно. vector<int> lst = {1, 4, 8, 10}; мне кажется информативней чем lst = [1, 4, 8, 10]
  3. В С# при желании тоже можно вводить динамическое программирование(в .нет 4 появилось). Также имеются многие функциональные вещи в шарпе.

К чему это я всё, просто к примеру имея VS 2010 и решарпер + огромный набор либ на все случаи жизни сишарп имеет абсолютно теже удобства для быстрого создания прототипов и легкого кодинга, но при этом имеет большой отрыв в скорости конечного продукта. Наверное после все плюшек шарпа - питон уже не вызывает таких эмоций. Всё это ИМХО :-)

> ответить
@ikalnitsky
Красиво форматировать код в наше время не проблема, например Visual Studio делает это сама, но не заставляет.

Ключевое выделил жирным в цитате. Во-первых, то, как это делает студия, может не соответствовать convention'у разработчиков (конечно, может студия позволяет это настраивать и все такое, но гибко ли?). Во-вторых, надо приучать себя сразу писать красиво, а не надеятся на тулсы. Если человек код отформатировать нормально не может, то о какой элегантности дизайна проекта может быть речь вообще? Имхо, это говорит о том, что человек злостный быдлокодер.

Да и вообще, фигурные скобочки как идентификаторы блока были убраны из python потому, что они являлись избыточными. Все нормальные программисты делают отступ для блока. Вот и напрашивается вопрос: зачем нужны фигурные скобочки, если есть отступ?

Динамическая типизация - перенос ошибок которые можно отловить при компиляции- в рантайм. Да и мне статика кажется удобнее, ИМХО конечно.

Если код пишется нормально, то никаких проблем с этим быть не должно. Т.к. тип является избыточным на мой взгляд. Мы должны программировать более в высоких абстракциях. ;)

vector<int> lst = {1, 4, 8, 10}; мне кажется информативней чем lst = [1, 4, 8, 10].

И чем же? Декларация lst = [1, 4, 8, 10] однозначно говорит, что это list. А целые числа говорят, что это целочисленный список. Вопрос: зачем тогда слова vector и int? Имхо, даже комитет C++ начал понимать это и попытался ввести уродские литералы и ключевое слово auto.

p.s: Haskell программист из тебя не получится: там типы не указываются, хотя язык со статической типизацией.

К чему это я всё, просто к примеру имея VS 2010 и решарпер + огромный набор либ на все случаи жизни сишарп имеет абсолютно теже удобства для быстрого создания прототипов и легкого кодинга, но при этом имеет большой отрыв в скорости конечного продукта.

Абсолютно нет. :) C# и близко не походит на python. Количество библиотек? Да, под него их много. Но в остальном разница просто огромна. Нет декораторов, нельзя создать отдельно функцию (что за бред? что мне, создавать утилитарный класс со статическими методами?). А по скорости.. хех, не думаю, чтобы C# обгонял Python.

Если взять реализацию PyPy, то на некоторых тестах PyPy не проигрывает аналогичному продукту на C. JIT делает своё дело на ура. :)

> ответить
@Csharpman

@ikalnitsky, ну насчет форматирования спорить не буду, о вкусах не спорят, как говорится:-) Да литералы новые конечно жесть, а auto клевая вещь, но думаю юзать ее будут только при длинных шаблонных типах, а так как писали int value=5; так и будут писать. Все таки в больших проектах нужно вести сумасшедшую строгость, и чтобы компилятор бил по рукам на каждый шаг влево. C# по любому будет быстрее питона, т.к. насколько я помню все объекты в питоне создаются в куче, а на стеке нельзя. Честно говоря, мне питон почемуто напоминает мой первый ЯП - qbasic :) Псевдокод который можно запустить, поэтому он видимо так и популярен:-)

> ответить
@ikalnitsky
C# по любому будет быстрее питона, т.к. насколько я помню все объекты в питоне создаются в куче, а на стеке нельзя.

C# быстрее C? Вообще сравнивать нельзя, т.к. в одних случаях Python будет быстрее, а в других C#. Я в этом уверен. Все будет упираться в ту часть компилятора/транслятора, которая ступорит производительность. Например, в том же C++ стандартный потоки ввода/вывод медленнее чем в том же Python (если не ошибаюсь, где-то читал сравнение). Но ведь никто не будет отрицать, что на C++ выходят медленные приложения? :)

Честно говоря, мне питон почемуто напоминает мой первый ЯП - qbasic :) Псевдокод который можно запустить, поэтому он видимо так и популярен:-)

Даже не знаю, что здесь общего :) Абсолютно разные языки. А то, что код на пайтоне похож не английский язык — это наоборот хорошо. Я за readability, в противном случае можно вообще до ассемблера опуститься. ;)

> ответить



Comment system uses reStructuredText. [show/hide tip]