在这里,我定义了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
?
答案 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
。