У меня была идея, мотивированная некоторой документацией, которую я прочитал в учебном пособии по библиотеке повышения MTL.
Основная предпосылка заключается в том, что я хотел бы использовать шаблоны, чтобы дать мне ошибки проверки типов во время компиляции для вещей, которые в остальном одинаковы.
А именно, допустим, у меня есть две единицы измерения: радианы и градусы. Самый очевидный способ получить безопасность типов - это определить 2 класса:
struct Radian
{
float rad;
}
struct Degree
{
float deg;
}
Это все хорошо, за исключением того, что я могу сделать что-то вроде
func()
{
Radian r;
Degree d;
r.rad = d.deg;
}
Было бы хорошо, если бы я мог пометить такое назначение как ошибку типа времени компиляции. Это привело меня к рассмотрению следующего:
struct Degree {};
struct Radian {};
template <class Data, class Unit>
struct Quantity
{
Data val;
Quantity<Data,Unit>() : val() {}
explicit Quantity<Data,Unit>(Data v) : val(v) {}
};
typedef Quantity<float,Radian> Rad;
typedef Quantity<float,Degree> Deg;
Теперь эквивалентный код функции func (), использующий типы Rad и Deg, будет отмечать это присваивание как ошибку времени компиляции (и с явным набором, даже выполнение чего-то столь же простого, как Rad r = 2.0, считается ошибкой времени компиляции) .
Что мне действительно нужно, так это float, у которого есть это свойство дополнительных единиц, которое можно использовать для отлова логических ошибок во время компиляции (т. Е. С использованием степеней в функции, которая ожидает радианы), но для всех намерений и целей эти вещи плавает.
В качестве общего вопроса, что вы думаете об этом подходе? Я немного обеспокоен тем, что это неправильный способ достижения моей цели, но у него странная привлекательность. Кроме того, есть ли «черта» или что-то вроде проверки концепции буста, которую я могу использовать, чтобы определить, что Данные «плавающие». Наконец, есть ли способ унаследовать реализации операций по умолчанию, такие как «<<», чтобы мне не пришлось реализовывать их все вручную в классе «Количество»? </p>