chr*_*ris 5 c++ templates compiler-errors implicit-conversion
#include <iostream>
struct Int {
int i;
operator int() const noexcept {return i;}
};
int main() {
Int i;
i.i = 1;
std::cout << i;
}
Run Code Online (Sandbox Code Playgroud)
但是,这无法在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;
}
Run Code Online (Sandbox Code Playgroud)
以下是错误的相关部分:
错误:'operator <<'不匹配(操作数类型是'std :: ostream {aka std :: basic_ostream}'和'String')
std :: cout << s;SNIP
template 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,它们具有相同的模板参数.我真的不确定为什么它不能像它那样获取隐式转换Int.为什么它可以使用int,但不是std::string?
该运算符是一个自由template函数.在匹配template函数参数时,不会检查用户定义的转换,而是使用类型模式匹配(替换).
理论上,SFINAE过载使用std::is_convertable<>可以做你想要的,但是当定义operator<<输出a std::string到a 时,没有使用该技术basic_ostream<char>.
输出类的手动超载basic_ostream<...>将解决您的问题.
我会这样做:
struct String {
std::string s;
operator std::string() const {return s;}
friend std::ostream& operator<<( std::ostream& os, String const& self) {
return os<<self.s;
}
};
Run Code Online (Sandbox Code Playgroud)
它具有不创建浪费副本的额外好处.