Написание качественного кода на C++ не должно быть трудной задачей. Если разработчик будет следовать рекомендациям, приведенным в C++ Core Guidelines, то он будет писать исключительно надежные, эффективные и прекрасно работающие программы на C++. Но руководство настолько переполнено советами, что порой трудно понять, с чего начать. Начните с «Красивого C++»! Опытные программисты Гай Дэвидсон и Кейт Грегори выбрали 30 основных рекомендаций, которые посчитали особенно ценными, и дают подробные практические советы, которые помогут улучшить ваш стиль разработки на C++. Для удобства книга структурирована в точном соответствии с официальным веб-сайтом C++ Core Guidelines.
Например, гипотетически вы инженер-программист, а не инженер-электронщик. На уровне 1, физическом уровне, вы чувствовали бы себя очень некомфортно, и вам было бы гораздо удобнее работать на уровне 7, прикладном уровне. Возможно, вы слышали термин «full-stack-инженер». Такой инженер способен продуктивно работать на всех уровнях. Но это мифическое создание вряд ли встречается в реальности.
Также подумайте, что случится, если перегруженная версия функции, принимающая логическое значение, будет добавлена после определения конструктора, принимающего std::string const&.
Продвижение означает расширение представления типа. Например, объект типа short может быть продвинут до объекта типа int (такое преобразование называется целочисленным продвижением), а объект типа float может быть продвинут до объекта типа double, что известно как продвижение с плавающей точкой.
Преобразования отличаются от продвижения возможностью изменения значения, что может отрицательно сказаться на точности. Например, значение с плавающей точкой можно преобразовать в целое число, округлив до ближайшего целого. Кроме того, целочисленные значения и значения с плавающей точкой, перечисления без указания области видимости, указатели и типы указателей на члены могут быть преобразованы в логическое значение. Эти три ранга являются концепциями, унаследованными от языка C, и от них невозможно отказаться из-за необходимости поддерживать совместимость с C.
Это частично охватывает стандартные последовательности преобразований. Преобразования, определяемые пользователем, выполняются двумя способами: либо с помощью неявного конструктора, либо с помощью неявного оператора преобразования. Именно этот тип преобразований мы ожидаем в нашем примере: наш аргумент char const* преобразуется в std::string через неявный конструктор, который принимает char const*. Это так же очевидно, как нос на вашем лице. Но с какой целью мы втянули вас в это обсуждение особенностей разрешения перегрузок?