Комментарии 52
Любой опытный программист знает о разнице в обработке путей между Windows и UNIX-системами:
… а разделителем путей служит обратный слеш “\”
Вында очень давно понимает прямой, так что с этим пунктом можно не морочиться.
шаблонные RAII вида std::lock_guard guard(mutex); станут короче: std::lock_guards guard(mutex);
точно короче?
Избегайте вложенности пространств имёнЭто почему?
Тоже заинтересовал этот вопрос.
namespace foo {
namespace bar {
namespace something {
...
}
}
}
Это почему?
Мне не хотелось бы, чтобы появление простого синтаксиса вложенных пространств имён привело к росту их числа. По моему опыту программисты часто злоупотребляют: пишут длинный многоуровневый namespace (30-40 символов) там, где конфликтов имён быть не может, и в итоге просто неудобно пользоваться.
Заголовки потом выглядят отвратительно.
При этом я ничего не имею против namespace boost::detail
, но даже boost::algorithm::any_of
мне уже не нравится.
Но вы можете считать это предвзятым мнением автора =)
P.S. ещё есть отличное правило — каждая строка в коде не длиннее 80 (100, 120) строк. Вложенные пространства имён норовят его нарушить, а вводить постоянно синонимы — в cpp-файлах неудобно, в заголовках неприемлемо.
Но вы можете считать это предвзятым мнением автора =)Именно таким его и остается считать. Если остальные нововведения вполне хорошо объясняются с технической точки зрения и можно наглядно показать, что это ведет к тем или иным выгодам (как в понятности кода и сокращению пространства для ошибок, так и в его эффективности), то данное утверждение является вкусовщиной, не более того.
а вводить постоянно синонимы — в cpp-файлах неудобно, в заголовках неприемлемо.Еще одно предвзятое мнение автора.
висячих ссылок (англ. dangling pointers)
Так висячии ссылки или таки висячии указатели?
(Как дополнительные скобки при присваивании в условии.)
А ещё очень странно, что нельзя прыгать на метки case с помощью goto хотя бы внутри switch, хотя это и есть метки для прыжка.
Метка для прыжка - это идентификатор (строка, начинающаяся с буквы или подчёркивания).
Метка switch - числовая константа.
Совсем разное!
Но в C# разрешили ведь.
Неудивительно, что c# перегружен сахаром. Ведь решения принимаются там единоначально, в отличие от c++, где каждое изменение сопровождается дебатами.
Нет никакого смысла вводить в c++ конструкцию goto case и ломать совместимость со множеством компиляторов, когда такое же поведение достигается буквально минимальными затратами
switch (num) {
case 1:
case_1:
break;
case 2:
goto case_1;
}
for (auto&& [key, value] : map)
Опечатка или какая-то фича, неподдерживаемая MS'ом? webcompiler.cloudapp.net, 19.12.25715.0 (x86). Last updated: Sep 25, 2017:
Compiled with /std:c++17 /EHsc /nologo /W4
main.cpp
main.cpp(18): error C2440: 'initializing': cannot convert from 'std::pair<const _Kty,_Ty>' to 'std::pair<const _Kty,_Ty> &&'
with
[
_Kty=std::string,
_Ty=std::string
]
main.cpp(18): note: You cannot bind an lvalue to an rvalue reference```
А в чем соль использования в этом месте rvalue reference? Почему не const auto &?
Это perfect forwarding. Почитать можно, например, здесь — https://eli.thegreenplace.net/2014/perfect-forwarding-and-universal-references-in-c/
Но есть минус: для string_view не гарантируется наличие нулевого символа на конце
Я так уже и вижу тысячи разных багов, которые тут могут возникнуть.
Так для std::string
тоже не гарантируется же. В чём принципиальная разница?
Ну да, не будет этот класс совместим с частью сишных функций, хотя про тысячи багов это вы, конечно, преувеличили. Плюсовые функции не ожидают 0 в конце строки, проблемы могут возникнуть только с некоторыми сишными функциями, с которыми в любом случае надо быть осторожным, при работе из плюсов. Очевидно, что string_view
просто абстракция над парой (const char* data, size_t len)
, так что по другому и быть не могло.
Сама необходимость явно вызывать c_str()
означает, что пользователь должен знать об этом ограничении, чтобы его невелировать. Отсутствие c_str()
у string_view
будет ему намекать, что с этим классом так делать нельзя. В общем, не выглядет для меня серьезной проблемой.
Вопрос не в удобстве а в быстродействии. Если вы на место std::srting&
передадите const char*
произойдёт неявное копирование с выделением памяти в хипе. Здесь — не произойдёт. Если вам нужна 0-терминированная строка, вы всегда можете скопировать string_view
в string
явно.
Отдавать сишным функциям указатели на внутренности плюсовых классов всегда было небезопасно, так что тут ничего не поменяется. Что касается того, чтобы писать используя С-строки — это намного менее безопасно и удобно. Пример типичных компонентов, где string_view
может дать большой прирост производительности — различные парсеры, которым накладно выделять память, каждый раз, когда они хотят отдать пользователю токен.
Так у него ещё и c_str() нету? Как им пользоваться вообще? В 9 случаях из 10 получается удобнее иметь const& string.У меня был один момент, когда я прямо мечтал о string_view.
XML-парсер, который на вход принимает XML в
std::string
и принимает класс-визитор, который получает оповещения о прохождении нод и атрибутов. Методы класса получали параметр const std::string&
с именем/значением ноды/атрибута. Если визитору было интересно значение, он себе его копировал в свой std::string
, или парсил в int
.Такое решение требовало создания новых строк на каждом атрибуте, а не каждый атрибут интересовал визиторы.
string_view
тут был бы очень кстати (визитору всё равно, в каком виде приходят данные — string, char* или string_view).XML-и были большие, десятки мегабайт.
Как же надоели чёртовы любители Boost! Варитесь в своём мирке, руки прочь от стандарта!
Куча разных подходов, разных стилей, да даже в том, в каком стиле именуют стандартные классы, функции и т.д. разобраться не могут.
Зато модульность и рефлексию добавить уже двадцать лет как не могут.
Сделали бы форк — в одном месте хипстеры и Boost с прочим сахаром, а в другом настоящее расширение языка — в виде тех-же модулей.
Такое ощущение что боятся лезть под капот языку, или уже не знают как.
- maybe_unused
- nodiscard
- fallthrough
maybe_unused — через нижнее подчеркивание, чтобы разделить слова — логично.
nodiscard — одним словом, хотя слова «nodiscard» — не существует, ожидаемо наличие нижнего подчеркивания, но его нет.
Как я понимаю, эти атрибуты одновременно добавили, почему такая неконсистентность, что помешало?
Восемь возможностей C++17, которые должен применять каждый разработчик