Овърлоуд на bool оператора
В скелета на трета задача (TypedStream) намерих следния код:
// Vector2D.h
operator std::string() const {
std::ostringstream s;
s << "(" << this->x << ", " << this->y << ")";
return s.str();
}
Това беше ново за мен и докато го разучавах (пре)открих много други неща, свързани с овърлоудването на оператори в C++.
Особено интересно в контекста на тази задача ми се стори овърлоудването на bool, което дава възможност за булева проверка на стейта на инстанция от класа:
TestClass test;
if (test) {
...
}
В конкретната задача го имплементирах така (private method в TypedStream, защото не го ползвам извън класа):
explicit operator bool() const {
return this->stream.good();
}
Горното работи за задачата, но бърза справка показва, че овърлоудването на bool оператора може и да има нежелани странични ефекти (като кастване през bool до 0/1), решаването на които е свързано с доста по-сложна имплементация:
Restrain Conversion Operators with the "Indirect Conversion" Idiom
Според тази статия explicit (от C++ 11) би следвало да реши този проблем:
Since bool is convertible to int and this conversion is not a user defined conversion, enabling an implicit conversion from a type X to bool means, any object of type X can also be implicitly converted to int, giving 0 or 1. Therefore objects of type X could participate in overload resolution in many unexpected cases which can make using X a nightmare. That has been a known problem for a long time, and looking up “safe bool idiom” will give you a lot of information of how not to covert to bool but something that is only convertible to bool. Luckily, C++11 solved the problem by introducing explicit conversion operators and stating that the compiler shall try to explicitly cast objects to bool if they are used in a boolean context, as in `if (x)`.
Въпросът ми е най-вече към Жоро:
Правилно ли съм разбрал, че explicit решава всички проблеми, произтичащи от овърлоуда на bool оператора, и ако не е така, какво друго трябва да се направи за правилната му имплементация?