Pull to refresh

Comments 20

Я-то наивно полагал, что вы при помощи C++11 предложите красивое решение поставленной проблемы. Но:
Acceleration acc1 = Value<Unit<1, 0, -2> >(2); // Ускорение = 2 м/с/с. Ошибки нет.

явно нельзя назвать красивым и понятным решением. Уж лучше:
Speed sp =100m/20s;

А вообще, комментарии перед определением метода / функции, поясняющие значение параметров — наше все. На мой взгляд.
По поводу комментария. Если вы решите изменить назначение параметров, то вам придется править комментарий. Об этом часто забывают, и комментарий становится источником ошибок при использовании вашего кода (про это писал вроде С. Макконелл в книге «Совершенный код»).
Хочу еще добавить. Поменяв назначение параметров вы, как мне кажется, не сможете эффективно исправить все места использования вашей функции без статической проверки типов компилятором.
Начинать надо было с литералов, а не в P.S. о них писать,

За подобные конструкции в коде:
Acceleration acc = Value<M>(100) / Value<S>(10) / Value<S>(1); 

надо наказывать.

А за подобные:
Acceleration acc1 = Value<Unit<1, 0, -2> >(2);

убивать.

Не поймите меня неправильно.
Все эти конструкции легко «обмазываются» typedef-ами. Здесь решил оставить так для большей наглядности.
Обмазываются, до тех пор пока не потребуется вычислить и сохранить, ну не знаю, какой-нить момент импульса вращательного движения в нерелятивистской механике (взял с потолка).
typedef Value<Unit<1, 0, -1> > Speed

Как бы в C++11 уже можно и >> писать, без пробела.

PS: не увидел в статье «best practice». На что смотреть-то?
Основной посыл статьи — не лениться писать классы для передаваемых параметров в ваши функции и проверять как можно больше на этапе компиляции.
Что именно в таком подходе относится к «стилю С++11»?
Я думаю что вот это:
  • Использование новых ключевых слов (constexpr, auto)
  • Не писать макросы для того, что реализуется на шаблонах (пример с оператором деления)
Такое ощущение, что вы «C++11» с «plain C» сравниваете.
И тут врывается F# с units of measure:

[<Measure>] type m
[<Measure>] type s

> let accl = 10.0<m/s^2>;;

val accl : float<m/s ^ 2> = 10.0

> let sp = 100.0<m/s>;;

val sp : float<m/s> = 100.0
Какой-то лютый песец на шаблонах… лучше уж
increaseSpeed(double speed_ms)
overengineering во все поля(
Тогда уж лучше increaseSpeed(double speed_meters_per_sec), ато ещё спросят как вы в миллисекундах скорость измеряете.

А вообще идея статьи взята из выступления Страуструпа на GoingNative2012 (но примеры и реализация как-то неудачно обрезаны), лучше посмотреть, если ещё не.
Вообще-то Страуструп в своём выступлении говорит, что такой приём с шаблонами для единиц измерения доступен в C++ уже 10 лет, но он широко не использовался из-за неудобства, это же просто нечитаемый код. Зато с выходом C++11 и появлением пользовательских литералов, есть возможность записывать это всё в человеческом виде и широко использовать.
Видели бы вы, чем это заканчивается…
Вы изобрели boost::units:
quantity<length> L = 2.0*meters; // quantity of length
quantity<energy> E = kilograms*pow<2>(L/seconds); // quantity of energy

Причем, применять такое стоит разве что в сложных физических расчетах — чтобы не ошибаться в формулах.
Sign up to leave a comment.

Articles