为什么不能将cout与用户定义的转换用于std :: string?

时间:2017-03-24 08:39:16

标签: c++ type-conversion operator-overloading implicit-conversion cout

在这里,我定义了Date,并指定了用户定义的转换。

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;
    }
};

转换为string时效果很好。

Date d(1, 1);
string s = d;

但为什么不能直接与cout一起使用?

cout << d << endl; // The compiler complains that there is no suitable type marching << operator

但是,如果我使用char*代替string进行用户定义的转换,我可以直接将其与cout一起使用。为什么呢?

operator const char*() { 
    ostringstream formattedDate;
    formattedDate << month << " / " << day;
    dateStr = formattedDate.str();
    return dateStr.c_str();
}

PS。我知道直接重载<<对输出很有效。但我的问题是:为什么不能将<<与用户定义的转化用于std::string

1 个答案:

答案 0 :(得分:13)

请注意,std::string是来自模板std::basic_string的实例化,the signature of operator<< for std::string确实是:

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);

然后对于cout << d;,必须推导出std::basic_string的模板参数;但是type deduction does not consider implicit conversions;

  

类型推导不考虑隐式转换(上面列出的类型调整除外):这是重载解析的工作,稍后会发生。

这意味着扣除会失败;那么没有候选功能是可行的。

但是operator<< for const char*没有这样的问题;隐式转换生效,然后工作正常。

要解决此问题,您可以使用显式转换来避免模板参数推断;或者直接在operator<<类型上重载Date