Pull to refresh

Comments 86

Осилить C++ стал «челленджом», не успеваем вникать в детали нового стандарта, как появляются другие нововведения.
Круто конечно, когда язык держит программиста за яйца, но в скором времени «знать C++ полностью» будет означать решать задачу «P=NP» :)

P. S. По мне, если еще и появится возможность/библиотека для разработки GUI, то C++ определенно захватит мир! Жду с нетерпением, а то уж больно многовато в последнее время.нет-чиков завелось…
Есть ведь Qt для разработки GUI. Чем он вам не угодил?
Да Qt вообще все умеет. Мы тут в соседнем посте собирали под андроид на плюсах приложение с кумлем, норма
Qt это отдельная либа, думаю, что автор Dehumanizer говорил о светлом будущем, когда компоненты, для работы с GUI войдут в std::gui :)
Пожалуй только жирностью библиотек. Иногда хочется к малюсенькой консольной утилите прикрутить GUI, который бы весил соразмерно ей самой, а не на 2-3-4 порядка больше.
Полностью поддерживаю. Большинство С++ программистов еще даже С++03 полностью не знают, а тут уже столько нового.
Да ну, бросьте, C++11 гораздо няшнее C++03, одно только auto чего стоит!
Я не говорю о том, что С++11 плох. С++ отличный мультипарадигменный язык. Но у него есть один весомый недостаток, пожалуй, единственный недостаток — это программисты, которые на нем пишут. В С++11 есть невероятно много возможностей писать не читаемый говнокод, гораздо больше, чем в любом другом языке.
Наверное, это Вы еще код на objective c не читали/не писали ;)
C++ из-за строгой типизации все-таки дает меньше способов заговнокодить, вынуждает держаться в рамках приличий.
чтобы изучить C++ можно попробовать поучаствовать в www.cppgm.org/
ну, как всегда, знать желательно по-максимуму, а использовать на 20%
Да вообще-то знать C++ полностью даже на уровне стандарта 2003 года очень и очень сложная задача. В этом легко убедиться, поузнавав у коллег, кто смог набрать на BB 5 баллов :)
Кстати, вот интересная статейка на тему фундаментальных недостатков языка С++. Конечно С++14 хорош, но добрая треть перечисленного по прежнему актуальна
dlang.ru/10-prichin-pochemu-u-cpp-net-budushhego
[]()->auto& { return f(); } // возврат ссылки

М-да. С++ люблю, но иногда мне кажется, что я никогда не смогу успеть за нововведенями. Боюсь иногда встретить подобные конструкции в коде и не разобраться :)
int& (*fpi)(int*) = [](auto* a) -> auto& { return *a; }; // OK

Ваш пример еще ладно, но вот это уже хуже.
Слева у нас значит сигнатура в виде указателя на функцию сишную. Возращает ссылку на int, принимает указатель на int, справа у нас лямбда, принимающая указатель на auto, возращающая ссылку на auto, в теле замечено разыменование этой самой переменной а.
Не так уж и сложно всё.
А кто-то говорил, что это сложно? Я просто привел пример из статьи, который при беглом чтении распарсить сложнее, чем у Ockonal.
Еще чуть-чуть и возможности создания гикнутых конструкций перла будут побиты :)
С такими темпами компилятор С++ скоро осознает себя и начнёт захватывать мир.
Скорее такими темпами скоро будет проще написать программу-генератор компилятора C++, принимающую на вход человеческий текст стандарта, нежели реализовывать все особенности «вручную».
с такими темпами на подготовку C++-джуниора будет уходить не 5-6 лет, как сейчас, а годиков этак 15. А еще Саттер и Александреску без хлеба не останутся со своими книжками «взорви себе черепную коробку с C++ — новые убийственные задачи!»
я ещё до сих пор на старом стандарте сижу, понемножку начал браться за С++11, руки дрожат..., а тут ещё С++14. С деталями разбираться веки вечные.
Не парьтесь особо, вспомните историю, в 2014 должен выйти, в 2015 выйдет, к 2017 будет поддержка в компиляторах, к 2019 — в основных библиотеках, с 2020-го артихекторы начнут принимать решения о разработке с его использованием. Время есть.
Не волнуйтесь, C++14 выйдет в 2014, это же не ворох новых фич как в С++11, а тот самый, допиленный, C++0x, который планировался изначально, т.е. доработанный, и более однозначный. Даже в статье написано, что С++14 это багофикс к С++11.
Разработчики Qt помню убивались, что еще многие годы не смогут использовать С++11 в коде из-за необходимости быть совместимыми с кучей компиляторов. Ну то есть они могут заюзать что-то, отключаемое макросами на этапе компиляции (типа конструктора перемещения), но не могут использовать, к примеру auto (потому, что придется код 2 раза писать — ну и смысл?).
Агу, вообще D — это революция в языках программирования, которую можно будет по настоящему использовать для системного программирования, как сейчас используется С, но не используется С++.
Ревлюция — это Rust (тайпклассы, алгебраические типы с паттерн матчингом, регионы и т. д.). D — эволюция («каким был бы С++ если из него выкинуть обратную совместимость и добавить GC с объектами-ссылками»), ничего принципиально нового не предлагающая.
«Знаю C++» — немногие после 14-го стандарта смогут это честно заявить.
А разработчики компилятором разве уже не воют на Луну? Я в курсе, что MS подтянул C++ в 13-ой студии, что gcc поддерживает все новинки почти сразу, но сможет ли это долго продолжаться? Появится фрагментация языка (Видимо, она уже есть, проблема стоит не так остро)?
Ну а когда появились компиляторы, поддерживающие 98 стандарт полностью? CBuilder6 2002 года точно не весь буст компилирует, например. С++ развивается в своем духе (как обратно-совместимый язык с value-семантикой и отсутствием GC) в довольно предсказуемом направлении. Capture-by-move в лямбдах я, например, в Clay реализовывал и в итоге пришел примерно к тому же выводу необходимости обобщенной инициализации вместо тысячи capture-by-{val|ref|move}. Знать его целиком уже никто не обязан — фичи пилятся ad-hoc для упрощения жизни конкретных людей.
Не соглашусь, одним языком и STD всё равно не обойтись в работе, нужно знать ещё, как минимум, Boost, а значительная часть функционала C++11 и С++14 пришла как раз из Boost. Да и сам язык прилично улучшился:
auto — избавляет от кучи проблем при работе с шаблонами, и вообще полезно и удобно.

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

Появление нормальных shared_ptr и unique_ptr, а в С++14 ещё и возможность вообще абстрагироваться от ручной работы с памятью через new и delete, а это очень сильно упрощает жизнь (не забываем про особенности исключений в С++, и отсутствие finally).

Наконец то появившейся for each, избавляющий от написания кода в стиле К.О.

И ещё вагон и маленькая тележка фич, которые делают С++ удобнее, и безопаснее.
Кстати насчет for each. Нет способа красивого обхода по контейнеру с конца с помощью этой конструкции?
Ну все-таки это некрасивые решения. Странно, что в stl не скопировали адаптеры.
Вот вам лямбда на С++98, хотя пишу по памяти, не уверен точно, что можно таким образом инитить.

struct {
int i;
foo operator() (boo b) { bar(i, b); }
} lambda = { 100500 };

Не так уж и сильно длиннее. Функциональность ровно такая же.
Лямбда в будет удобнее тем, что она может быть определена там, где непосредственно используется, а в случае с функциональным объектом его придется определять в некотором другом месте:

#include <iostream>
#include <thread>

int main (int argc, char * argv [])
{
    std::thread work {[] {std::cout << "Hard work!" << std::endl;} };

    return 0;
}


#include <iostream>
#include <thread>


struct FunctionalObject
{
    public:
        void operator ()() {std::cout << "Hard work!" << std::endl;}
}

//
// Lot of code...
//

int main (int argc, char * argv [])
{
    std::thread work {FunctionalObject ()};

    return 0;
}
Сюрприз: структуры (в том числе и функциональные объекты) можно объявлять и определять прямо в коде функции перед использованием.

Единственный гемор (не принципиальное ограничение, просто длинно кодить) — это если нужно захватить локальные переменные.
> Сюрприз
Мда… Действительно сюрприз…
Сюрприз: локальные классы не могут быть параметрами шаблонов в C++03.
У меня в коде анонимная структура, ее прямо можно передавать в std::thread

#include <iostream>

template <typename Callback>
void foo(Callback callback)
{
    int bar = 1;
    callback(bar);
}

int main(void)
{
    int capture = 2;
    struct {
        int captured;
        void operator () (int bar) {
            std::cout << bar << captured;
        }
    } lambda = { capture };
    foo(lambda);

    return 0;
}


Правда собирается только в clang и мне малость некогда разбираться как это собрать в gcc. Ну и вроде бы совсем анонимной эту лямбду увы не сделать.
> Правда собирается только в clang и мне малость некогда разбираться как это собрать в gcc.

На gcc 4.7.3, собралось без единого изменения по команде:
g++ -std=c++0x main.cpp
Так фича в том чтобы без ключа -std=c++11 собиралось.
Локальные структуры как параметр шаблона разрешены только в С++11. Странное ограничение, но есть такое.
А как-то раз сели и написали компилятор под си, потом под плюсы… с нуля
optional

С нетерпением ждём Either, List и остальные монады ;)
template <typename T> optional<T> bind_optional(optional<T> ma, std::function<optional<T>(T)> f) {
    if (ma)
        return f(*ma);
    else
        return ma;
}
В каком месте стандартной библиотеки я могу найти этот код?
А в каком месте несуществующей пока библиотеки вы хотите его искать?
Теперь из C++ нужно больше убрать, чем добавить
Убирать нельзя, из-за обратной совместимости. Но можно не рекомендовать к использованию (см., к примеру auto_ptr).
Но тем не менее спрошу, что, и по какой причине, следует убрать из С++?
В HTML когда-то проблему обратной совместимости решили разделением стандарта на strict и transitional версии. Уверен, что тот же подход отлично подошёл бы для C++.

Итак, что нужно убрать из C++:
1. Все встроенные типы с implementation-defined размером: short, int, long, long long заменяем на int16_t, int32_t, и т.п. Как вариант, фиксируем размер short, int, long в битах. Всё равно другие типы на нормальных архитектурах не встречаются, а для экзотических есть C. Плюс 100 к портабельности.
2. Propagation операндов аримтетических операций к int — убираем нафиг и забываем как страшный сон. typeof(short(2) + short(2)) == int — отличный выстрел, прямо в ногу!
3. Аналогично char и wchar_t заменить на char8_t, char16_t, char32_t.
4. Жёстко зафиксировать float = IEEE 754-2008 single-precision, double = IEEE 754-2008 double-precision.
5. enum class не нужен, простой enum должен реализовывать эту функциональность.
6. Implementation defined — зло и ересь, половина кода MSVC-only, половина gcc-only. Стандарт должен ограничивать число возможных вариантов.
7. Undefined behaviour в большинстве случаев туда же. Стандарт должен быть строже в отношении возможных интерпретаций.
8. STL не нужна. Нужен удобный механизм подключения любой стандартной библиотеки (например import "github.com/stroustrup/stl" в стиле Go). Для фич языка, которые должны взаимодействовать со стандартной библиотекой (например typeid), должной быть определено бинарное ABI.
Только в HTML5 убрали версии.
По некоторым пунктам:
3. Сразу тогда символы в Unicode;
8. Нужна. Без нее либо убирать очень нужные вещи, либо хардкодить их.
Я имел в виду HTML 4.0/XHTML 1.0. К HTML5 форматирование уже перевели на CSS, и обратная совместимость со старыми тегами вроде font уже не была столь большой проблемой.

3. Соблазн ограничиться одной кодировкой огромен, и многие другие языки так и сделали, но на C++ пишется много софта, который работает и с multi-byte кодировками (текстовые редакторы, например). К тому же разные фреймворки используют разные кодировки Юникода.
8. Если стандартизировать интерфейс на бинарном уровне, единой стандартной библиотеки не потребуется, будет много совместимых со стандартом библиотек (а конкуренция = хорошо).
Так и сейчас много совместимых со стандартом библиотек, каждый компилятор свою предоставляет.
Я вижу две проблемы с нынешними стандартными библиотеками.
1. С++ ABI не стандартизировано, библиотеки поддерживают только тот компилятор, с которым они поставляются. Из-за этого написание модульных программ (программ с плагинами) на C++ затруднительно, и требует большого количества костылей.
2. Функциональность стандартной библиотеки стандартизирована. В сочетании с первой проблемой это уничтожает стимулы развивать стандартную библиотеку. Например, сравните функциональность класса QString из QT 5 и класса std::basic_string из Microsoft STL.

Я считаю, что нужно как раз обратное: чётко описанное в стандарте C++ ABI, и минимум огранический на стандартную библиотеку.
Скажите, а чем вам не нравится Java? Там все это есть. Будет ли лучше, если из С++ сделают еще одну Jav`у?
Мне нравится Java, и я нередко на ней пишу. Но у каждого языка своя ниша. На Java невозможно писать высокопроизводительные научные приложения, у C++ с этим сильно лучше, но я не вижу ничего плохого, чтобы в некоторых чертах он стал похож на Java.
> невозможно писать высокопроизводительные научные приложения

Возможно
И как мне писать под CUDA или под Xeon Phi на Java?
Очень просто — вам нужно написать нужный участок кода на C, и предоставить к нему простой SOAP-интерфейс, который затем подключить со стороны Java :) Еще возможно использовать JNI, но крайне не рекомендуется — ведь вы потеряете 500% расширяемости!
SOAP то зачем? Есть же нормальные протоколы.
Во-первых, один пример невозможности писать высокопроизводительные научные приложения на Java не означает, что их нельзя писать на Java в принципе.
Во-вторых, элементарное гугление показывает, что для Java и CUDA есть jcuda. Для всего прочего всегда есть JNI.
Согласен с korynd про 3 и 8, но нужно оставить ещё 7 — Undefined behaviour.
UFO just landed and posted this here
Есть мнение, что С++14 с новым Qt станет совместим с яваскриптом на уровне исходников
UFO just landed and posted this here
В принципе статью уже много пользователей прочитало и, судя по всему, вопросов ни у кого не возникло, но в любом случае спрошу:

1. > Атомные (atomic) объекты предоставляют atomic_exchange функцию…
Возможно Атомарные будет более уместно?

2. > std::cout << "She said \"Hi!\"; // вывод: She said "Hi!"
Тут не нужна еще одна кавычка?
int& (*fpi)(int*) = [](auto* a) -> auto& { return *a; }; // OK

Еще немного и С++ будет похож на смесь Brainfuck и PL/I
Очень миленький синтаксис. Надо просто один раз попробовать.
Интересно, они когда-нибудь додумаются объявить язык устаревшим и посоветовать всем перейти на D, или им подсказать?
Не так страшен C++, как его инструментарий.
Почему-то скачав с github'а проект на Python, Perl, Javascript, Delphi, даже на Plain C, я могу нажать одну кнопку — и он сразу же соберётся и запустится (в случае чистых сей — может не с первого раза, но со второй-третьей попытки уж точно). И только блин в случае C++ надо заниматься подбором ключей и версий компилятора методом брутфорсинга, т.к. логики там никакой нет в принципе. А потом ещё и линкер начинает ругаться, т.к. там не стыкуется то, что получилось в результате обработки шаблонов и прочих замечательных конструкций.
Чем дальше, тем сложнее заставить чужой C++ проект хотя бы просто собраться без того, чтобы потратить пару недель на изучение профессии сборщика данной конкретной пачки кода.
Ну без примера это голое заявление, я довольно частую компилирую опенсорсные проекты, особых трудностей не испытывал.
Под линуксами — да, конечно.
А попробуйте ffmpeg под виндой. Или, например, Aegisub. А можно еще vapoursynth. И это еще вполне адекватные примеры.
Собрать всё из этого реально. Вопрос в том, сколько на это надо потратить усилий «с нуля».
Доберусь до винды — попробую, вы меня заинтриговали.
Так ffmpeg это проект, написанный на «чистом» Си, разве нет?
Хорошо когда язык такими темпами развивается. Я конечно не С++ программист но слежу за этим языком издалека, видимо с универа осталась привязанность. Да, как печально смотреть на java после вот таких вот статей, и не только потому что он безнадежно отстает в темпах развития а так же потому что текущие казалось бы стабильные версии java не перестают нас радовать свежими багами и дырами в безопасности. Ладно хоть появляются новые языки и развиваются такие как С++.
Хорошо, когда арбузы такими темпами растут. Я, конечно, не аграрий, но слежу за арбузами издалека, видимо, с бахчи осталась привязанность. Да, как печально смотреть на огурцы после вот таких вот статей, и не только потому, что они безнадежно отстают в темпах роста, а также потому, что текущие, казалось бы, вкусные сорта огурцов не перестают нас радовать свежими вредителями и потертостями кожуры. Ладно хоть появляются новые фрукты и развиваются такие, как арбузы.
Это была попытка публичного унижения, через трололло? Вы форумом не ошиблись, здесь вам не sql тчк ru. Я думал что на хабре люди свободно могут выражать свое мнение, без опаски напороться на всяких быдло-троллеров.

Автору спасибо за статью, я всегда рассматривал c++ как очень консервативный язык, и еще раз сожалею что некоторые менее консервативные языки не имеют такого динамизма в своем развитии. Данную идею я никому не навязываю, это лишь мое сугубо личное мнение. И мне очень жаль осознавать тот факт что на данном ресурсе троллинг набирает все больше оборотов.
auto vglambda = [](auto printer) {
   return [=](auto&& ... ts) {   // OK: ts - это упакованные параметры функции
       printer(std::forward<decltype(ts)>(ts)...);
   };
};
auto p = vglambda( [](auto v1, auto v2, auto v3)    
                       { std::cout << v1 << v2 << v3; } );
p(1, 'a', 3.14);  // OK: выводит 1a3.14


В этом примере можно легко убрать
std::forward<decltype(ts)>
Sign up to leave a comment.

Articles