Я нахожусь в ситуации, когда у меня возникает соблазн поместить два оператора преобразования в один класс.Обычно я бы избегал этого, как чума.Но с C ++ 11 и операторами явного преобразования кажется, что я хочу достичь и разумно, и безопасно.Однако мне нужна проверка работоспособности.
Рассмотрим следующий класс («Расстояние»), предназначенный для связи значения расстояния с его единицей измерения.
enum class Unit { None = 0, Meter = 1, Foot = 2, }; // None means INVALID
class Distance
{
Unit m_unit;
double m_value;
public:
Distance() : m_unit(Unit::None), m_value(0.f) {} // construct invalid
Distance(Unit u, double, v) : m_unit(u), m_value(v) {}
Unit unit() const { return m_unit; }
// Two functions that I would like to make into cast operators:
double value() const { return m_value; }
bool valid() const { return Unit::None != m_unit; }
// Cast operators I would LIKE to add and use. Implicitly cast to
// double but in "if()" scenarios, cast to bool to check validity
operator double() const { return m_value; }
explicit operator bool() { return valid(); }
};
Поскольку объект Distance предназначен для обработки, как если бы он был двойным значением (большую часть времени), я подумал о добавлении неявного двойного приведения (выше).Но в определенных контекстах расстояние может считаться недействительным, представленное значением единицы измерения Unit :: None.В этом случае мне очень нравится идея добавить явное логическое приведение.
Конечная цель состоит в том, чтобы иметь возможность заменить код, который в настоящее время выглядит так:
void doSomething(bool b) {}
void doSomething(double d) {}
void DumpDistance(const Distance& dist)
{
if (dist.valid())
std::cout << dist.value() << std::endl;
doSomething(dist.valid()); // properly calls bool version
doSomething(dist.value()); // properly called double version
}
, в следующее:
void DumpDistance(const Distance& dist)
{
if (dist) // treated as bool (good)
std::cout << dist << std::endl; // treated as double (good)
doSomething(dist); // calls double overload (good)
}
В моем тестировании кажется, что явный оператор bool добивается цели.Но я не уверен.Похоже, требуемые перегрузки вызываются.Но у меня есть встроенное отвращение к операторам кастинга, сгоревшим во мне в темные старые времена 1990-х годов.
Поэтому мой вопрос:
Это действительно так же безопаснокак кажется? Есть ли какой-то очевидный случай, в котором я пропускаю, когда компилятор жаловался бы на неоднозначное преобразование или, что еще хуже, беззвучно вызывает один оператор, когда мне нужен другой? *
(Длябыть ясным: я не спрашиваю ни о необходимости этого, ни о его удобочитаемости. Только об опасностях двусмысленностей или преобразований во время компиляции, которых я не хочу делать. Мне нужно закрепить концепцию явных операторов преобразования в моей голове.)