Pull to refresh

Comments 10

В c++ бывает очень удобно все переменные всегда хранить в СИ, а для удобства ввода и читаемости кода использовать User-defined literals:
long double operator "" _feet(long double d)
{ 
    return d * 0.3048; 
}

auto meter = 3.28084_feet;
std::cout << meter << std::endl; // prints 1.0

Те же самые user-defined literals очень удобно использовать при работе с комплексными числами, кватернионами, трехмерными векторами, датами и прочей структурированной информацией.
Я был бы не против, если бы всё хранилось в СИ, но тут проблема другая — данные хранятся в разных единицах и нужно избежать ошибок конвертации. Самое банальное — забыл конвертировать, и сложил метры с миллиметрами.
Так реализуйте все вычисления в СИ. Конструкторы замените методами типа Length.FromMeters(...), Length.FromInches(), снаружи вычисления везде производите не с непонятными double и int, а с Length. Ну и собственно при необходимости отобразить где-то значение в виде конкретной единицы реализуйте get-методы типа Meters(), Millimeters(). Подобным образом реализован TimeSpan в C#, и как выяснилось чуть позже — TTimeSpan в Delphi.
Ладно еще если метры с миллиметрами где-то перепутал. Перегрузка операторов помогает — можно райзить эксепшн при попытке каста, или конвертировать и хранить всё в СИ.
А если вот где-то ускорение в метрах за секунду в квадрате суммируется с метрами?
Получается что в перегрузке операторов нужно перечислить все возможные типы, в которые оно может кастится.
Жаль, что нельзя принудительно сказать компилятору что эти типы не кастятся, или хотя бы ворнинг выводить.
Так если у Вас явно не определены операторы приведения или присвоения для разных типов — компилятор и будет ругаться.
Ну да, это известная фича Си — нет типов.
На Паскале, скажем, как раз разные типы просто так не приводятся друг к другу.
Ну, или в Аде. 0_0
Зачем хранить в разных единицах? На входе преобразовать в одну. На выходе в другую.
Единственный случай когда используются данные сильно разных порядков (т.е. к диаметру Земли прибавить диаметр атома), но такие вычисления часто бессмысленны.
Если не хотите переводить метры в миллиметры, просто не пишите оператор приведения. При попытке одновременной работы вас проверит компилятор, иначе вычисления могут(обязательно) прерваться на последнем этапе.
Немного из альтернативной вселенной, просто от нечего делать:
type time is range -2147483647 to 2147483647
		units
			fs;
			ps = 1000 fs;
			ns = 1000 ps;
			us = 1000 ns;
			ms = 1000 us;
			sec = 1000 ms;
			min = 60 sec;
			hr = 60 min;
	end units;
Простите за необознанность, но это на каком языке?
Вы производительность такого кода тестировали? Потому что оверхед при перегрузках там есть, и даже с inline-ом. Просто не прикольно, когда сложение двух чисел начинает работать в 8 раз медленнее.
Sign up to leave a comment.

Articles