I have a following example (with overly safe boolean type):
#include <cstdlib>
struct boolean_type
{
explicit
boolean_type(bool _value)
: value_(_value)
{ ; }
explicit
operator bool () const
{
return value_;
}
private :
bool value_;
};
struct A
{
A(int const _i)
: i_(_i)
{ ; }
boolean_type operator == (A const & _other) const
{
return (i_ == _other.i_);
}
private :
int i_;
};
bool t()
{
return A(0) == A(0);
}
int main()
{
return EXIT_SUCCESS;
}
It is well-known that such code containing an errors: "could not convert '(((int)((const A*)this)->A::i_) == ((int)other.A::i))' from 'bool' to 'boolean_type'" in return statement of bool A::operator == (A const &) const
and "cannot convert 'boolean_type' to 'bool'" in return statement of bool t()
. But what the risk here? Why there are not explicit conversion here in both cases? Why are implicit? In fact we explicitly specify the returning type bool
in second case and static_assert(std::is_same< bool, decltype(std::declval< int >() == std::declval< int >()) >::value, "!");
as such!
Additionally want to say:
Due to the specified obstruction I cannot simply replace all entries of the bool
to my super-safe boolean_type
(which is mocked-object) in my user code, because, say, in return statement of boost::variant::operator ==
uses above construction, that treats there as implicit conversion. Similar obstructions are not unique.
return
is a very special case. You have spelled out the type to convert to a few lines above. This is not the same as converting to some random type that is never mentioned in the function. Then it becomes a matter of taste. I think having to repeat the type in every return statement is a pain. - Marc Glisse