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

?

+3


source to share


1 answer


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

.

+9


source







All Articles