#include <iostream>
struct Int {
int i;
operator int() const noexcept {return i;}
};
int main() {
Int i;
i.i = 1;
std::cout << i;
}
但是,this fails to compile on GCC 4.8.1:
#include <iostream>
#include <string>
struct String {
std::string s;
operator std::string() const {return s;}
};
int main() {
String s;
s.s = "hi";
std::cout << s;
}
以下是错误的相关部分:
错误:'operator <<'不匹配(操作数类型是'std :: ostream '和'String')std :: cout << s;剪辑模板std :: basic_ostream <_CharT,_Traits>&std :: operator <<(std :: basic_ostream <_CharT,_Traits>&,const std :: basic_string <_CharT,_Traits,_Alloc>&)operator <<(basic_ostream < _CharT,_Traits>&__os,/ usr / include / c /4.8/bits/basic_string.h:2753:5:注意:模板参数推断/替换失败:main.cpp:25:18:注意:'String'不是派生自'const std :: basic_string <_CharT,_Traits,_Alloc>'std :: cout << s;
我只使用 std::cout
和 std::string
,它们具有相同的模板参数 . 我'm really not sure why this wouldn'能够像 Int
那样获取隐式转换 . 为什么它适用于 int
,而不是 std::string
?
2 回答
该运算符是一个免费的
template
函数 . 在匹配template
函数参数时,不会检查用户定义的转换,而是使用类型模式匹配(替换) .理论上,使用
std::is_convertable<>
的SFINAE重载将能够执行您想要的操作,但是当operator<<
输出std::string
到basic_ostream<char>
时,未使用该技术 .将类输出到
basic_ostream<...>
的手动重载将解决您的问题 .我会这样做:
它具有不创建浪费副本的额外好处 .
<<运算符似乎有一个重载池,其类型不是std :: string . 正如我通过使用clang编译器看到的那样 .
编译器执行从String到std :: string的隐式转换,但它与任何已定义的<<运算符都不匹配 .
如果为std :: string定义<<运算符,它将起作用
您可以在此处找到有关同一问题的更多详细信息:http://forums.codeguru.com/showthread.php?432227-RESOLVED-Implicit-conversion-to-std-string
正如一篇文章中所见;