Why can't cout be used with custom conversion to std :: string?
This is where I define Date
and set a custom transform.
class Date {
private:
int day;
int month;
string dateStr;
public:
Date(int _day, int _month) : day(_day), month(_month) {}
operator const string() {
ostringstream formattedDate;
formattedDate << month << "/" << day;
dateStr = formattedDate.str();
return dateStr;
}
};
Works well when converting to string
.
Date d(1, 1);
string s = d;
But why can't you use it cout
directly?
cout << d << endl; // The compiler complains that there is no suitable type marching << operator
However, if I use char*
instead string
for a custom transformation, I can use it from cout
directly. Why?
operator const char*() {
ostringstream formattedDate;
formattedDate << month << " / " << day;
dateStr = formattedDate.str();
return dateStr.c_str();
}
ps. I know that overloading <<
directly will work well for output. But my question is, why can't it be used <<
with a custom conversion to std::string
?
source to share
Note that std::string
is an instance from a template std::basic_string
, the signature operator<<
for isstd::string
indeed:
template <class CharT, class Traits, class Allocator>
std::basic_ostream<CharT, Traits>&
operator<<(std::basic_ostream<CharT, Traits>& os,
const std::basic_string<CharT, Traits, Allocator>& str);
then a cout << d;
template parameter should be output for std::basic_string
; but type inference ignores implicit conversions ;
Type computation does not consider implicit conversions (other than the settings listed above): this is a job to resolve the overload that happens later.
This means that the deduction will fail; then no candidate function is viable.
But operator<<
forconst char*
has no such problem; the implicit conversion takes effect and then works fine.
To solve this problem, you can use an explicit conversion to avoid subtraction of the template argument; or overload operator<<
by type Date
.
source to share