I have a Rectangle
class with conversion operators to both double
and std::string
:
class Rectangle
{
public:
Rectangle(double x, double y) : _x(x), _y(y) {}
operator std::string ();
operator double ();
private:
double _x, _y;
double getArea() {return _x * _y;}
};
int main()
{
Rectangle r(3, 2.5);
cout << r << endl;
return 0;
}
I don’t understand why operator double()
is invoked, rather than operator std::string()
.
As far as I know, according to C++ wikibook,
operator double
is used to convert Rectangle
objects to double
.
So what's going on here? Is it related to the fact that an int
is passed to the constructor? If so, why?
Since you did not provide an
operator<<
overload forRectangle
, the compiler considers other overloads for which the arguments can be converted to the parameter types.If any of the overloads are templates, then template argument substitution happens to them before overload resolution. The compiler tries to deduce the template parameters from the types of the arguments supplied to the function.
The
string
overload is not considered because of a template argument substitution failure:Template argument substitution does not consider user-defined conversions, so the compiler can't deduce the types
CharT
,Traits
, orAllocator
from the typeRectangle
, so this overload does not participate in overload resolution. (Recall thatstd::string
is just a typedef ofstd::basic_string<char, std::char_traits<char>, std::allocator<char>>
.)Therefore there is one overload of
operator<<
which is a better match than any other, and that is thedouble
overload. Not a template, but a member function of a class template.There is nothing special about double-overloading than other primitive types overloadings. In this case, it is the only primitive overload available. The compiler will behave the same for int, char, etc..
Notice that if we would have more than one primitive type overload the compiler will throw
You do not have an operator to output the rectangle to the stream.
cout
does have an overload that takes adouble
and your class can be implicitly converted to adouble
so that is chosen.The reason the string overload is not selected and is not considered as an ambiguity is because
operator <<
for a string is a member function and is not included in the member overload and non member overload set ofcout
. If we comment out theoperator double
we can see we get a compiler error.If we want to have the
operator string
called then we would need to explicitly castr
into a string. Live Example