I write a class Fraction
, and would like to display Fraction object with std::cout
:
Fraction f(3, 5);
std::cout << f << std::endl;
I know overloading operator <<
can be used for this display purpose. But I can also overload operator type()
function, and when only with operator double()
(let type
be double
), I can still std::cout << f << std::endl
.
Even more, I can also implement operator std::string()
. But, when the mentioned 3 overloaded operator functions all exist, without explicitly type conversion, which one is called when doing std::cout << f << std::endl
? This really makes me curious, is this undefined behavior denpending on compiler implementation, or if there is some rule for scoring the closest/most suitable function to call?
To reproduce, use the following code:
#include <iostream>
#include <string>
class Fraction
{
public:
Fraction(int num, int den=1):
numerator(num), denominator(den) {}
operator double() const {
std::cout << "[operator double()]";
return numerator*1.0 / denominator;
}
operator std::string() const {
std::cout << "[operator std::string()]";
return std::to_string(numerator) + "/" + std::to_string(denominator);
}
private:
int numerator;
int denominator;
#ifdef OVERLOAD_STREAM_OP
friend std::ostream& operator << (std::ostream& os, const Fraction& frac);
#endif
};
#ifdef OVERLOAD_STREAM_OP
std::ostream& operator << (std::ostream& os, const Fraction& frac)
{
std::cout << "[operator <<]";
os << std::to_string(frac.numerator) << "/" << std::to_string(frac.denominator);
return os;
}
#endif
int main()
{
Fraction f(3, 5);
double d = 4 + f;
std::cout << "\n--- now let's print\n";
std::cout << "f: " << f << std::endl;
std::cout << "f: " << std::string(f) << std::endl;
std::cout << d << std::endl;
return 0;
}
The output on my ubuntu 20.04:
(base) zz@home% clang++ fraction.cpp
(base) zz@home% ./a.out
[operator double()]
--- now let's print
f: [operator double()]0.6
f: [operator std::string()]3/5
4.6