Pull to refresh

Comments 166

Теперь необязательно ставить пробел между скобками > >… ура)) Больше всего порадовало auto, только из-за него перешел за 10 студию.
BOOST_AUTO с абсолютно аналогичной функциональностью рабтает уже давно.
К сожалению знакомство с бустом движется безумно медленно. Знаком только с парочкой классов (мультипоточность, сеть)…
Ну как аналогичной — для работы во всех компиляторах BOOST_AUTO каждый свой тип надо зарегистрировать через BOOST_TYPEOF_REGISTER_TYPE, что удобным никак назвать нельзя…
Каюсь, никогда ничего не регистрировал, в gcc и студии just works…
Я разве что свои обвески с константностью и ссылками добавил, как-то так pastie.org/2780816
Так для этих компиляторов он поди в auto и разворачивался.
GCC давно этот стандарт поддерживает.
После прочтения даже появилось слабое желание изучить c++
Смотрю я на с++ и понимаю на сколько все-таки читабельнее современные языки программирования. Хотя может все дело в привычке…
Неа. Только за синтаксис их лямбд надо убивать
[](int x, int y) { return x + y; }
[](int x, int y) -> int { int z = x + y; return z; }

[]        //no variables defined. Attempting to use any external variables in the lambda is an error.
[x, &y]   //x is captured by value, y is captured by reference
[&]       //any external variable is implicitly captured by reference if used
[=]       //any external variable is implicitly captured by value if used
[&, x]    //x is explicitly captured by value. Other variables will be captured by reference
[=, &z]   //z is explicitly captured by reference. Other variables will be captured by value


Это — звиздец. Понятно, чем продиктованый (отсутсвием GC, следящим за происходящим), но тем не менее звиздец
Что конкретно в синтаксисе не понятно и сложно?
Сравни с лямбдами в любом другом языке (кроме PHP :) ).

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

[=, &x, &y, z](int a, std::vector<int>::const_iterator it) -> int { кусок кода }


Это, особенно когда вокруг дофига другого кода, не является понятным. Легкость — понятие относительное
С++ язык для тех, кто хочет контролировать процесс полностью
Именно поэтому я считаю с++ программистов именно «Программистами» с большой буквы. Они как хирурги в современном мире программирования ) А остальные так… педиатры всякие, медбратья )
Смешно, действительно смешно.
Человек может полностью контролировать очень ограниченное число сущностей.
Микроменеджмент нужен в достаточно малом количестве случаев.
Это Ваше мнение, и, я думаю, многие C++ программисты с Вами не согласятся.
Тем кому нужен микроменеджмент пишут на (embedded) c, а не на c++ с shared_ptr.
Из Ваших слов можно сделать только один вывод: Вы не знаете(или не понимаете), что такое shared_ptr и как его использовать. Ровно как и имеете неправильное представлении о C++. Если Вы уверены в своей правоте, тогда, пожалуйста, приведите пример потери контроля в C++.
«Многие» — это те, для которых борьба с крохами важнее производительности, в частности собственной.
Микроменеджмент синоним слова производительность? Если уж взялись за рассмотрение «собственной производительности», то посмотрите в сторону статической типизации, ведь синтаксис lambda в С++ является прямым развитием этой идеи — избавление от ошибок на этапе компиляции. В частности, от ошибок которые могут быть спровоцированы использованием переменной(по ошибке), которая не должна быть использована в lambda. С++ минимизирует подобные ошибки посредством строгого контроля над тем, что попадает в closure и как оно туда попадает.
> Микроменеджмент синоним слова производительность?

Нет, не синоним

> С++ минимизирует подобные ошибки посредством строгого контроля над тем, что попадает в closure и как оно туда попадает.

Не надо выдавать желаемое за действительное. Такой синтаксис лямбд — исключительно вынужденная мера, потому что в С++ нет ни малейших способов 100% отследить жизненный путь захватываемых переменных, для этого нужен GC или подобные механизмы.

Я не говорю уж о таких маразмах, как этот, например
Не надо выдавать желаемое за действительное

Я могу сказать Вам тоже самое. Если нужно продлить жизнь переменной нужно передавать её копию и никакой GC не нужен. Указатели-же. должны контролироваться программистом или должны быть обернуты в shared_ptr, и проблемы с ними будут решены.
Я не говорю уж о таких маразмах, как этот, например

В чем здесь маразм, в том, что автор по незнанию наткнулся на проблему вызванную ограничением языка? Именно поэтому в описании lambda, в стандарте, this выделен отдельно, т.к. трактовать его стоит особым образом.

То, о чем говорите Вы справедливо для this и не справедливо для остальной части языка.
> Указатели-же. должны контролироваться программистом или должны быть обернуты в shared_ptr, и проблемы с ними будут решены.

Дадада. Все С++-программисты, я в курсе, мне уже рассказали, все прекрасно знают, осведомлены обо всех подводных камнях и прекрасно все контролируют

> В чем здесь маразм, в том, что автор по незнанию наткнулся на проблему вызванную ограничением языка?

>> Не надо выдавать желаемое за действительное
>Я могу сказать Вам тоже самое.

> С++ минимизирует подобные ошибки посредством строгого контроля над тем, что попадает в closure и как оно туда попадает.

Так вот, выдаете желаемое за действительное вы, а не я. Все, о чем я говорю } это о том, что весь этот маразм с синтаксисом лямбд, с перекладыванием микроменеджмента на плечи программиста, с маразмом вроде описанного по ссылке — это все следствия именно языка и невозможности его по человечески расширить так, чтобы всего этого избежать.

И только упертые сиплюсплюсники начинают рассказывать сказки про то, что «С++ язык для тех, кто хочет контролировать процесс полностью», «С++ минимизирует подобные ошибки посредством строгого контроля» и прочая и прочая

;)
Простите, а вы говорите про программистов или про «дешевых enterprise мартышек»?)
Если про вторых, то да, им не свойственно знание языка, умение ими оперировать, и, конечно же, они совершенно без понятия чем отличается shared_ptr от weak_ptr и unique_ptr, но и них и задачи иные — набить побольше строк кода за меньшую стоимость :)
Конечно может показаться что я грубоват, но поймите, если человек не в состоянии разобраться в таких мелочах как умные указатели и специфичный синтаксис лямбда выражений, считая их исчадиями ада, то, как мне кажется, он не осилит и более сложных вещей.
Простите, я говорю про программистов, которые программируют на том или ином языке. Хотите вы этого или нет, но там будут и гуру вроде Саттера и толпа индийцев.

Поэтому когда говорят общие фразы типа «С++-программисты все умеют», мне, и любому здравомыслящему человеку, хочется долго и безудержно смеяться.

Как и от любых других общих фраз в этом топике.

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

Ойойой камень в мой огород, я так полагаю. Да-да, каюсь, именно синтаксис лямбд мне кажется исчадием ада, и я никогда не разберусь в чем-то сложном, ага ага :))

В чем-то сложном не смогут разобраться люди, которые считают, что такой синтаксис появился именно потому что «С++ язык для тех, кто хочет контролировать процесс полностью», а не люди, которые критикуют такой синтаксис, основываясь на ограничениях языка.
Вот в душе не пойму, что сложного в синтаксисе лямбд. Разобрался за 2 минуты. Я что, гений что-ли? Или очередной Фауст, продавший душу Мефистофелю?
И вообще: лямбды же это не более, чем анонимные функциональные обьекты с определенными вариантами поведения.
> Вот в душе не пойму, что сложного в синтаксисе лямбд.

Я уже говорил: сравните с любыми другими лямбдами в любом другом языке.
Лямбды я юзал и в других языках. Но в том же JS не так очевидно, что же происходит с захватом переменных. Списки захвата очень помогают. Что касается возращаемого значения, то тут свои ограничения строгая типизация дает. Но эти же ограничения весьма полезны, на самом деле, и помогают лучше оптимизировать код. Он банально быстрее работает из за отсутствия runtime проверок.
Да и если написать [&], то получатся ваши любимые лямбды из js.
Ох, очевидно, неочевидно.

Инструмент надо знать.

Остальные размышления про оптимизацию и статику тут не к месту.
Микроменеджмент нужен там где он нужен. Другое дело что с++ программист знает что это и как им управлять, чего большинство программистов других языков не знают и боятся как огня
Как я люблю эти заявления про мегакрутость С++ программистов. Причем — всех сразу, скопом. Не надо расказывать сказки про С++-программистов, знающих, что это и как эим управлять.
Кстати вчера вот буквально был на Симфони(ПХП) конференции и там совсем вроде не глупый парень заявляет — не экономьте на памяти, плюс минус 100 объектов в памяти это не страшно. Надеюсь вы не это имеете в виду?
Нет не это. Но в общем случае он прав. Надо всегда смотреть на результаты профайлинга. Скорее всего проблема будет не в «плюс минус 100 объектов в памяти»
Это эдакая защита от дурака. Нефиг в рот первую попавшуюся бяку тянуть.
Это сепер круто. Это то чего не хватает мне в javaScript и actionScript 3 иногда.
Чего не хватает? В JavaScript'е в лямбду захватываются все переменные, которые находятся в одной с лямбдой области видимости.
Вот именно контролдя за тем что захватится а что нет и не хватает. Иногда это имеет очень далеко идущие отрицательные последствия в виде утечек памяти.
Ну так аккуратнее надо программировать ;)
Вот для аккуратности и хочется иногда явно указать что попадёт в замыкание а что нет. Многие новички на этом сильно удивляются, почему же переменная нигде не используется а память утекла.
Ну, на самом деле такой вот микроконтроль новичкам тоже не особо поможет.
Зато не новичкам он поможет ОЧЕНЬ СИЛЬНО.
Если мы, как выше, говорим же программистах, которые, мол, уже и так все знают, и умеют все контролировать, то все упирается не столько в помощь, сколько в грамотное проектирование.
Не увидел в этом посте ничего, кроме воды.
Говорю проще: не новичкам грамотное проектирование поможет во много раз больше, ем выгода от явного объявления захватываемых переменных.
Не более общие, чем ваши заявления про помощь.
>>> Необходимость вручную определять, какие внешние переменные нам нужны и способ их затягивания внутрь лямбды — это звиздец.

К сожалению с плюсами знаком очень слабо, но подозреваю что вы говорите о замыканиях. ИМХО это очень правильно что замыкания не делаются неявно. В C# очень раздражает исправлять код за людьми вообще не понимающими что такое замыкания(ведь это так удобно, когда пишешь переменную из лексического контекста, и она подтягивает), ведь последствий этого они не понимают.
Ну да, а в С++ знание о том, что такое замыкание встраивается прямо в мозг, ага. Пример я уже приводил.
низкая квалификация и нежелание учиться это проблема C++?
Вы уже определитесь, да?

В C# замыкания — это плохо, потому что приходится постоянно подчищать, а в С++ — это хорошо, потому что там оно сразу в мозг встраивается?

Вне зависимости от языка подчищать придется, но почему-то у всех уверенность, что С++ программисты — это монстры, знающие все и вся, никогда не делающие ошибки и все знания им встраиваются прямо в мозг :-\
Я про C# не сказал ни слова.
А, сорри, это был предыдущий комментатор.

Низкая квалификация и нежелание учиться — это не проблема С++. Но только не надо рассказывать сказки про C++, как по него рассказывают все комментаторы в этой ветке типа:
— «Другое дело что с++ программист знает что это и как им управлять, чего большинство программистов других языков не знают и боятся как огня»
— «С++ минимизирует подобные ошибки посредством строгого контроля над тем, что попадает в closure и как оно туда попадает.»
— «я считаю с++ программистов именно «Программистами» с большой буквы. Они как хирурги в современном мире программирования ) А остальные так… педиатры всякие, медбратья»

И прочая и прочая.
Никаких сказок. Кто-то может, кто-то нет. А тот кто может — тоже ошибается и это будет справедливо как для capture all lambds, так и для non-captured lambds(по умолчвнию). Просто ошибки будут разного характера. В комитете по стандартизации C++ обсуждался вопрос дефолтного захвата переменных([=] по дефолту) и в результате решили от этого отказаться. Т.е. поддержать это можно уже сейчас, но это выльется в проблемы связанные с this и прочими указателями. К тому же выгода от подобного, лично для меня, выглядит весьма сомнительной.
Все, мною перечисленное, это именно сказки. Остальное, что вы описали — это не потому что С++ такой хороший, что контроль предоставляет, а именно из-за ограничений языка, что вы сами и пишете:
это выльется в проблемы связанные с this и прочими указателями


Но блин :) Это, почему-то, не мешает писать басни типа «С++ минимизирует подобные ошибки посредством строгого контроля над тем, что попадает в closure и как оно туда попадает.»

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

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

> низкая квалификация и нежелание учиться это проблема C++?

> ИМХО это очень правильно что замыкания не делаются неявно. В C# очень раздражает исправлять код за людьми вообще не понимающими что такое замыкания

низкая квалификация и нежелание учиться это проблема C#?

:-\

> Это простите помойка не поддающаяся ни чтению ни рефакторингу.

Дадада, а С++, безусловно, это позволяет решать эффективно и, более того, знание о том, как работают замыкания в С++ встраиваются прямо в мозг и никто никогда не совершит с ними ошибки, ага.

А в C# — все плохо, там язык виноват, ага :)))
На это язвительное утверждение я ответил ниже.
Да, я уже увидел и ответил :)
> низкая квалификация и нежелание учиться это проблема C++?

> ИМХО это очень правильно что замыкания не делаются неявно. В C# очень раздражает исправлять код за людьми вообще не понимающими что такое замыкания

низкая квалификация и нежелание учиться это проблема C#?
Язык определяет мышление. Это относится не только к языкам программирования но даже к простым языкам на которых мы с вами разговариваем.

Можно в принципе сказать, что любой программист(и не только) должен сперва думать, а потом делать, но реалии показывают обратное. В плюсах когда вы столкнетесь с замыканием вам ПРИДЁТСЯ подумать, или хотябы кратенько прочесть статью в спарвке, ну или хотя бы сообщение компилятора.

И в момент чтения должна появиться та самая мысль которая спасёт код от бытия говнокодом.
> В плюсах когда вы столкнетесь с замыканием вам ПРИДЁТСЯ подумать, или хотябы кратенько прочесть статью в спарвке, ну или хотя бы сообщение компилятора.

Не надо рассказывать сказки. В момент, когда быдлокодер увидит описание [=], он его сразу будет использовать и иметь веселый геморрой

Так что не надо рассказывать бред про:
> И в момент чтения должна появиться та самая мысль которая спасёт код от бытия говнокодом.

А то вас послушать — C++ программисты — это этакие рыцари без страха и упрека, у которых говнокода не может быть по определению.

Ага, ага, C# виноват, а как же
Давайте попробуем вернуться к началу дискуссии.

Я ответил на коментарий о явном объявлении замыканий. Моя идея была в том что это довольно полезно, именно по причине того что мы осознанно их начинаем использовать. Или хотя бы понимаем что «что-то не так как обычно». А раз «что-то не так» — то когда код начнёт работать не так как ожидали — мы возможно вспомним о той ошибке компилятора.

В то же время в шарпе ситуация другая. Мы пишем код, сами того не замечая используем переменную из лексического контекста, и абсолютно НЕОСОЗНАННО создаём замыкание. Мы врядли когда либо задумаемся о том как и почему происходит замыкание, как оно выглядит в ассемблерном представлении, и какие последствия этого. Из-за этого неверное поеведение нормального казалось бы кода — не сподвигнет нас вспомнить о замыкании.

Моя позиция изначально была именно такая. Разводить холивар о том что с++ девелоперы круче с# — я не собирался. Уже вроде наразводились лет 5 назад.

Ну и конечно исходя из вышенаписанного я считаю что язык может быть «виноват» в каких то привычках и особенностях программистов, каким бы смешным вам это утверждение не казалось.
> Мы врядли когда либо задумаемся о том как и почему происходит замыкание, как оно выглядит в ассемблерном представлении, и какие последствия этого.

Ну вот, опять начинается. А в С+ мы над этим задумываемся? Да не делайте мне смешно :)

Каждый инструмент надо знать. Мне почему-то ничего не мешает использовать лямбды осознанно в языках, в которых захватываются все переменные из области видимости лямбды.

> Ну и конечно исходя из вышенаписанного я считаю что язык может быть «виноват» в каких то привычках и особенностях программистов, каким бы смешным вам это утверждение не казалось.

Я не спорю. Но. Здесь почему-то каждый первый уверен в непогрешимости и крутости именно С++ программистов и С++, как такового. Несмотря на то, что весь этот цирк с лямбдами и их синтаксисом, далеко неявным поведением — это не потому что «С++ хорош», а потому что ограничения языка такие.
> Ну вот, опять начинается. А в С+ мы над этим задумываемся? Да не делайте мне смешно :)

А как же не задуматься если оно явно должно объявляться?
Задуматься о чем? О том, «о том как и почему происходит замыкание, как оно выглядит в ассемблерном представлении, и какие последствия этого.»

Вам самому не смешно? Этот инструмент точно так же будут использовать люди, который даже близко не имеют представления о том, в какие ассемблерные конструкции будет разворачиваться лямбда.

Более того скажу, даже если вы об этом задумываетесь, вы даже близко не имеете представления о том, как оно будет выглядеть в ассемблерном представлении.
Я имею представление как выглядит замыкание в C# в IL коде(это конечно не ассемблер, но C# и машинный асм слишком далеки, достаточно обычно IL код представлять), и могу обяъснить как оно работает. Reflector — любимый инструмент C# дева.

А вообще странно что вы так сильно склоняетесь к идее что люди увидев предупреждение или требование компилятора что то дополнительно объявить не полезут читать что либо, или не спросят тимлида своего.

Я бы именно так и сделал.

В целом я понял вашу мысль, не могу сказать что я с ней полностью согласен, но по крайней мере она вполне логична.

Возможно что вы и правы, но мой скромный опыт(личный) подсказывает почему то другое.
> А вообще странно что вы так сильно склоняетесь к идее что люди увидев предупреждение или требование компилятора что то дополнительно объявить не полезут читать что либо, или не спросят тимлида своего.

Каким образом вы это вывели из моих сообщений — уму непостижимо.

Я говорю только одно — сказки про мегаумных программистов на С++, которым знания замыканий и правила их использования автоматом вшиваются в мозг в момент выхода нового стандарта по С++ — это сказки.

Также, сказки про то, что все программисты С++ сразу в обязательном порядке думают о том, во что разворачиваются лямбды, как они выглядят в ассемблерном представлении, — это тоже сказки, и ничего более.

Честно признаться меня до одури утомило всё это словоблудие.

Моя мысль была такова: «Явное объявление замыканий полезнее неявного».
Если есть к ней дополнение\уточнения\претензии — давайте без отвлечения на гениальность\тупость С++ девелоперов.

Если вы хотите поговорить про плюсовиков, про то как вы их не любите, похоливарить на тему C# vs C++ — это не ко мне. Я серьёзно ничего не знаю про плюсы и плюсовых программистов. А если просто хочется сказать об этом — напишите статью, найдутся толковые люди и возможно поддержат вас.
Легко.

Берем ваши заявления:
ИМХО это очень правильно что замыкания не делаются неявно. В C# очень раздражает исправлять код за людьми вообще не понимающими что такое замыкания(ведь это так удобно, когда пишешь переменную из лексического контекста, и она подтягивает), ведь последствий этого они не понимают.


Откуда взялась уверенность, что при явном задавании передаваемых параметров люди ВНЕЗАПНО начнут понимать, что такое замыкания? [=] и [&] никто не отменял.

в шарпе ситуация другая… Мы врядли когда либо задумаемся о том как и почему происходит замыкание, как оно выглядит в ассемблерном представлении, и какие последствия этого.


Простите, объявляя замыкаемые явно, ВНЕЗАПНО программист начнет думать обо все этом? С какого перепугу?

Пока что на все мои возражения против этих высказывания я вижу только пассы руками и сказки про программистов, которые внезапно начинают все это думать и представлять.
Я всё-таки придерживаюсь мнения, что скорее мышление определяет тот язык программирования, на котором человек пишет программы и в течении жизни он находит язык, наиболее подходящий его мышлению или придумывает его или же остается неудачником.
Хех, ИМХО лучше всё таки знать и видеть явно где есть замыкание а где нет, нежели иметь бонус в виде отсутствия лишнего уточнения для замыкания в коде.

Именно из за отсутствия этого в C#(уверен не только в нем) многие неявно используют замыкания не понимая того во что разворачивается лексическое замыкание и конечно полседствий.
Делать то же самое в плюсах (исправлять код за людьми вообще не понимающими что такое замыкания) ничуть не проще.
Последствия бывают двух видов — некорректность и неэффективность.
На плюсах сделать некорректно не просто, а очень просто.
На шарпе просто сделать неэффективно.
Только вот оптимизировать корректное куда проще, чем корректировать оптимизированное.
А я то думал читабельность зависит от того кто пишет код, а оно вот оказывается что…
OK, тогда приведите пример читабельного кода на Braifuck.
Читабельность зависит не только от программиста.
Все мейнстримовые языки подходят к общему знаменателю. Приятно. Осталось дождаться полноценного вывода типов.
На самом деле в C++11 есть ещё decltype(), который как раз и реализует вывод типов. Не знаю, может Вы это не считаете полноценным, но даже не знаю, что тут ещё не хватает. Специально была расширена возможность декларации функции, при котором тип возвращаемого значение опирается на параметры (для упрощения записи в некоторых случаях).
Я не читал стандарт, но пишу :) [тут была самоирония]

Обязательно познакомлюсь со стандартом поближе, спасибо. Надеюсь, там действительно всё лучезарно и можно отбросить типизацию параметров при декларировании лямбд, например.
C удовольствием перейду на С++11, когда компиляторы наконец созреют. Странно, что в clang до сих пор не поддерживаются лямбды…
Вроде бы транковая 3.1 держит их, поэтому к весне наверное они будут. Меня вот делегирование конструкторов расстроило, точнее его отсутствие в студии.
Круто! Плюсы стали читабельными.
Только, в оригинале «you» было с маленькой. Не уподобляйтесь безграмотным рекламщикам
Круто! Плюсы стали читабельными.

Как сказать… Некоторые слишком увлекаются использованием вложенных друг в друга STL-алгоритмов с лямбдами, выглядит страшно.
Я думаю к лямбдам в C++11 все постепенно привыкнут, мне например тоже непривычно еще, хотя я на C++ много пишу.
Еще один огромный шаг к исчезновению C/C++ программистов :) Теперь наконец-то Си отдельно, Си плюс-плюс отдельно.

Единственно, что печалит — бОльшая часть из тонн уже существующего и поддерживаемого C++ кода никогда еще ооочень долго не увидит плюшек из нового стандарта в своем составе и лишь мизерный процент древних массивных проектов перейдет на использование новых компиляторов в ближайшее время. В итоге подозреваю нужно будет знать два языка: С++11 для собеседований, С++ для реальной работы после прохождения собеседования на C++11 :)
Ппхпшники так живут уже не первый год, а сейчас уже и 3 версии языка пора знать, 5.4 уже бета 2 и говорят более-менее стабильна.
Да ладно, в PHP нет такой принципиальной разницы. Все новые фичи не обязательны для использования. Если конечно вы не пилите Framework нового поколения.
примерно год как использую некоторые фичи из C++11 в продакшне. это лямбды, auto, decltype, variadic templates, инициализация через {} и thread+mutex из стандартной библиотеки. но переходить можно и постепенно.
Да, действительно, в современном мире языки программирования не развиваются, новых версий не выходит.
Опенсорс вот уже много юзает С++11 фичи, многие либы даже в описании содержат то, что они написаны в modern C++11 стиле, в Qt вводится потихоньку поддержка новых фич. Итого в пролете остается только энтерпрайз говно.
А не подскажите opensource проекты, желательно небольшие, которые используют активно С++11. Хотелось, посмотреть, может быть даже поучаствовать. Спасибо.
Товарищи, кто в теме, скажите стандартная библиотека сильно поменялась с 98-го?
С удовольствием бы почитал статью на тему, какие риски несет C++11.
Проблемы статического и динамического линкования со старым кодом С++98.
Сравнения скорости компиляции, скорости работы, потребления памяти старого и переписанного на C++11 кода.
Перспективы поддержки нового стандарта в компиляторах.
Добавлю вот такую ссылку C++11 Features in Visual C++ 11
Хотелось бы конечно поболее, но майкрософт что то не торопится. Хотя возможно к релизу и запилят поболее фич.
какие риски несет C++11

Те же, что С++98. Если вообще можно сказать, что язык «несет риски»
Проблемы статического и динамического линкования со старым кодом С++98

Какие тут могут быть проблемы, если линкуются библиотеки/объектники собранные одним компилятором?
Сравнения скорости компиляции, скорости работы, потребления памяти старого и переписанного на C++11 кода.

Подобные метрики слишком проектозависмые. Можно предположить, что код, который активно использует STL будет исполняться в сотни, а то и тысячи раз быстрее, за счет move semantics. Потребление памяти не уменьшится посредством самого стандарта, т.к. все, итак, контролируется программистом. Тут все в руках писателей компиляторов и библиотек. На данный момент нет ни одного компилятора поддерживающего хотя бы 90% стандарта.
Вот хоть убейте, но не понимаю радости относительно введения auto. Код сложнее читать, вопросы по поводу поддержки со стороны IDE…
Я например пока актино не использую C++11, больше в процессе изучения, но по крайней мере вот такой код выглядит намного элегантнее:
void MyClass::print() const
{
	for ( auto it = vec.begin(); it != vec.end() ; ++it )
		std::cout << *it << " ";
}

чем вот этот:
void MyClass::print() const
{
	for ( std::vector<int>::const_iterator it = vec.begin(); it != vec.end() ; ++it )
		std::cout << *it << " ";
}
for (auto i : vec)
    std::cout << i << " ";
выглядит еще элегантнее.

Но я всегда предпочитал std::copy вместо циклов.
for (auto i: vec) есть только в GCC 4.6+
так что пока придётся использовать auto
BOOST_FOREACH умеет все то же самое — итерацию по STL-контейнерам, по паре итераторов, по массивам.
private:
typedef std::vector инсерт_ёр_нейм;
Вроде как в той же статье Саттер рекомендует использовать не методы контейнеров, а внешние функции begin и end.
В *этом* примере — да. Но в реальной жизни код куда сложнее. А, как показывает практика, если где можно набыдлокодить, кто-нибудь там обязательно набыдлокодит.
Понятное дело, что в примере выше, лучше использовать std::for_each или for и range из нового стандарта, я просто привёл простенький пример именно на итераторы, как более компактнее становится код.
код с auto читать ни чуть не сложнее, если не злоупотреблять ею.
Заставлять использовать 4 типа указателей в сях… Я даже не знаю. Один тип указателя взрывал неокрепшую детскую психику, так что аж на C# и Java обучение переводят, что ж будет если надо помнить все три — и сырой (x*) и shared_ptr и uniq_ptr и weak_ptr? Да еще и где какой и как с ним жить… Йо хо хо. Вкупе с auto это выводит ошибку работы с указателями на новый уровень!
Вот он — прогресс!
Мне вот самому интересно как это всё будет выглядеть в реальных проектах, хотел бы почитать отзывы тех, кто уже в реальном промышеленном коде использовал эти фичи все. Но в любом случае C++ никогда не претендовал быть простым языком, согласитесь. Можно вспомить те же шаблоны и метапрограммирование, там ситуация не проще уж точно.
Да он просто для этого не предназначен, честно. Хаскель куда лучше для метапрограммирования, и как раз типы нигде писать не надо… (:
В тех проектах что используют буст — вероятно уже встречются разные типы указателей. Как минимум — shared_ptr, weak_ptr, scoped_ptr, auto_ptr.
А ведь там еще есть библиотека ptr_container =)
Мой проект например использует все вышеперечисленное, и все отлично работает. Людям не очень хорошо знакомым с глубинными свойствами конечно приходиться тратить какое-то время чтобы «въехать», но ошибок уж точно меньше чем если бы везде были бы просто указатели.
Тип указателей один, все то, что Вы перечисли является лишь обертками. Для человека пишущего на C++ «схватывание» подобной концепции не должно вызвать проблемы, т.к. никакой сложности они не представляют.
Нужен объект, который может быть скопирован во время исполнения и его копия будет использоваться как полноценный объект? shared_ptr
Нужен объект, который не будет скопирован? unique_ptr
Нужна копия объекта для реализации опроса его состояния на все время его жизни или вы столкнулись с проблемой циклических ссылок? weak_ptr

Когда использовать голые указатели? Никогда.
Более подробный ответ: Когда вы вынуждены. К примеру, в Qt, придется использовать голые указатели в parent/child отношениях. Если среда не вынуждает вас использовать голые указатели всегда используйте «умные обертки»
Я знаю когда и как их использовать. Я говорю что если их _заставлять_ использовать (а именно к этому идёт), это приведёт к тому, что при обучении вместо понимания логики «указатель» будет кашица «чего ему надо» и «какие там буквы надо магические тут написать?»
При разработке языка нужно думать как студентов учить или как сделать язык подходящим под современные требования и стандарты? С++ это язык с исключениями и подобные нововведения просто жизненно необходимы были в нём.
Как уже сказали, в shared/weak_ptr просто перекочевали из boost'а и ничего нового в них нет. unique_ptr — это что-то новенькое, надо будет въезжать (хотя если я верно понимаю — ещё не вникал в суть — это новая инкарнация auto_ptr), но опять же не так всё сложно. Без сборки мусора оставить только один тип указателей не получится: обычные указатели не всегда удобны из-за необходимости помнить в нужном месте вызвать delete, shared_ptr приведёт к утечкам памяти при циклических ссылках, weak_ptr в чистом виде вообще не нужен (без lock(), который возвращает shared_ptr им вообще пользоваться нельзя).
unique_ptr — это переименованный boost::scoped_ptr.
Да это действительно сложно, и почему же еще софт то пишут на с++?
Из-за мифической скорости. Ценой в тыщу багов на кило кода.
Именно, мифической!
Именно поэтому Microsoft делает ставку на C++, Microsoft верит в мифы. И лишь только бравые комментаторы хаобра знают истину.
Ага. Microsoft давно сделало ставку — .NET и JS+HTML5 ;) И багов в винде до той матери! ;)
datacompboy, Вы меня троллите? Вы build смотрели, channel9 посещаете?
Старый — потому что легаси.
Новый — только там, где нужна высокая скорость, и то, там чаще С++ приближенный к С.

Где бы то ни было еще С++ не нужен
Как там erlang для cuda поживает?
Сначала отвечаем себе на вопрос, где нужен CUDS, и где он используется, а потом задаем любые другие вопросы.
какие компиляторы эти возможности поддерживают?
Можете вот отсюда скачать компилятор MinGW, там есть поддержка как я понял большинства возможностей. Вот есть неплохая сводная таблица: какой компилятор, что поддерживает.
спасибо за ссылку, меня интересовал конкретно gcc
> «Если Вам нужно работать с объектом, который может пережить Вас, используйте сырой указатель.»
А почему нельзя использовать weak_ptr ли в примере c Node* parent?
Лично я не вижу причин не делать этого. weak_ptr'ы хороши ещё и тем, что есть возможность проверить, жив ли ещё объект, на который они ссылаются, в то время как с сырыми указателями всё не так просто.
Потомучто для этого пришлось бы наследовать класс Node от std::enable_shared_from_this и добавлять метод для получения этого самого shared_ptr. Я не знаю почему Герб не стал так делать; возможно, чтобы не усложнять пример. К тому же тут это явно избыточно, потомок не может существовать без родителя, а значит указатель всегда валиден или nullptr
Не про наследование от std::enable_shared_from_this не прав. В таком простом примере это излишне.
Как человек, пишуший ежедневно на плюсах, скажу: скомпилил себе gcc 4.7.5 из исходников, доволен. Так же доволен:
auto — очень удобно
for() — как заменитель для foreach удобно
лямбда функции — очень удобно
temlate<class… Args> — разное количество аргументов. Очень удобно. Больше не надо городить over9000 копипаст.

Пока что в gcc нехватает одной очень удобной фичи: использование конструкторов _этого_ класса (не родителя, не путайте) в других конструкторах _этого_ же класса.

На свой риск начал юзать его, так как думаю, что пока допишу проект, в репах таки появится 4.7.5.
Прикольно, а в clang'е наоборот сделали делегирование конструкторов. Удобно, чёрт-возьми!
Так в c++11 оно тоже есть, только в gcc не допилили ещё пока
UFO just landed and posted this here
Не провоцируйте народ! Может начаться холивар, ведь у каждого есть свои любимые учебники! ;)
На мой взгляд, если вы имели опыт программирования, то последняя книга от Страуструпа с голубенькой обложкой это самое то! Однако она научит как правильно писать клиентский код на С++. Поэтому когда захотите писать библиотеки, т.е. инструментальный код, то желательно почитать ранние книги Страуструпа. Дальше классика Майерса и уж потом ищите заклинание «решение сложных задач». Этого думаю, достаточно!
UFO just landed and posted this here
Если Вы Джавист — лучше Qt. При обучении Java встречал много знакомого из Qt. Также, Qt — кроссплатформенная штука, что тоже её роднит с Java.
Самое главное это 3 книги Майерса «Эффективное программирование на C++» (35, 55 советов и STL), это то, с чего следует начинать тому, кто знает синтаксис, но не знает подводных камней, а они есть.
я эти книги уже по несколько раз перечивываю, каждый раз что-то новое либо узнаю, либо разбираюсь в чём-то, еще к ним же можно добавить «C++. Священные знания», тоже материал преподносится в виде тем (правил). Полезная книга + куча подводных камней там описывается.
Мне эта книга категорически не понравилась. Скучно.
Вот Саттер «Сложные задачи...» — достойное продолжение Майерса. В том же духе, но сложнее.
Они кстати сейчас втроем с Александреску конференции делают. Это я к тому, что они в курсе существования друг друга =)
UFO just landed and posted this here
UFO just landed and posted this here
boost::enable_shared_from_this использую с 98 версией, эта семантика доступна давно :)
Вот у меня такой вопрос возник в связи с этими новыми умными указателями. Ведь по сути дела они за вас делают reference counting и при этом за счет разных типов (unique, shared, weak) решают проблему циклов. Оно, конечно, круто — безболезненное управление памятью, и при этом нет никакого сборщика мусора. Но в то же время все эксперты по GC и memory management говорят, что reference counting — это слишком медленно, и сегодня никто с его помощью сборщик мусора не пишет.

А в C++ теперь хотят его использовать. Как же так? Или я чего-то не понимаю?
Ну так никто и не собирается делать GC в C++ (тем более со счётчиком ссылок). Одно дело удалять неопределённое количество мёртвых объектов с помощью подсчёта ссылок и совсем другое — следить за одним существующим.
GC с refcounting работает также, как shared_ptr — каждый указатель сам следит за своим временем жизни. Также в дополнение используется трейсер для того, чтобы удалять циклы. Но трейсер совсем не обязательно запускать на каждом вызове GC. Так что по времени работа такого коллектора вполне сравнима с работой умных указателей.
На С++ можно написать библиотеку с GC, но она будет вещью в себе.
Вы, может быть, удивитесь, но в Java тоже иногда пишут сои аллокаторы, чтобы снизить нагрузку на GC: habrahabr.ru/company/odnoklassniki/blog/115881/ Тоже вещь в себе, но иногда полезная. Также и GC в C++ — его даже в стандарт хотели включить, но потом отложили на неопределенный срок.
Тогда придется пересматривать всю работу с указателями, в особенности с умными. GC очень плохо дружит с ручным удалением через delete.
1. Это слишком медленно в языках, где ВСЕ является ссылкой (аналог С++ — все обернуто в shared_ptr). На С++ так пишут только неадекватные товарищи типа некоторых лисперов).
2. Инкремент и декремент счетчика быстрые, пока приложение однопоточное. Основные тормоза дают new — выделение памяти в куче, и delete во время равенства ссылки нулю.
3. Это важный момент — не сам подсчет ссылок тормозит, а аллокатор.
4. Наиболее частая операция для умного указателя — разыменование — такая же по скорости, как для тупого.

Так что тормоза сделать можно только весьма искусственно — оборачивать все в многопоточный вариант shared_ptr, и это все постоянно создавать и уничтожать, не озаботившись указать для shared_ptr быстрый pool-аллокатор.
UFO just landed and posted this here
Ссылку на эксперименты? Как правило функциональщики на эрланге или хаскеле пишут быстрее чем на си даже при очень высоком уровне владения последним.
Осталось дождаться выхода по этому стандарту книги, подобной «Effective C++» Майерса :)
В текущем проекте настоял на использовании относительно свежего компилятора и включении поддержки (частичной, ибо в GCC 4.5 ещё очень многого нет) C++11.

На данный момент штатная поддержка лямбд мне столько времени и нервов сэкономила, что просто передать нельзя. В сочетании с возможностями метапрограммирования в Qt иногда получаются совершенно волшебные штуки :)
Кстати, небольшое примечание для идущих по тем же граблям. GCC 4.5 прекрасно работает с лямбдами, но в нём нельзя указать значение лямбда-параметра по умолчанию в списке аргументов функции. А вот в 4.6 это уже починили.
Взгляд google на проблему исключений в C++ (не обязательно С++11) с аргументацией: тыц
Ой, прошу прощения, это совсем в другую ветку.
Sign up to leave a comment.

Articles