可能重复:
Overload resolution failure when streaming object via implicit conversion to string
我知道这样做并不是一个好主意,但我真的想知道下面的代码无法编译的原因(即为什么“没有可接受的转换”):
#include <iostream>
#include <string>
class Test
{
public:
operator std::string () const;
};
Test::operator std::string () const
{
return std::string("Test!");
}
int main ()
{
std::string str = "Blah!";
std::cout << str << std::endl;
Test test;
str = test;//implicitly calls operator std::string without complaining
std::cout << str << std::endl;
std::cout << test;//refuses to implicitly cast test to std::string
return 0;
}
在Visual Studio 2010上,我收到此错误:“error C2679: binary '<<' : no operator found which takes a right-hand operand of type 'Test' (or there is no acceptable conversion)
”
<<
运算符是否隐式将std::string
转换为其他内容才能使用它?如果是的话,我需要在课堂上重载什么操作才能使这样的事情发挥作用?我拒绝相信我实际上需要使用operator char *
。
答案 0 :(得分:12)
operator<<(std::basic_ostream&, std::basic_string)
是一个函数模板,在模板参数推导期间不考虑用户定义的转换。您需要为您的班级重载operator<<
。
另一种选择当然是演员
std::cout << static_cast<std::string>(test);
答案 1 :(得分:11)
问题在于std::string
是模板std::basic_string<char>
的特化,而operator<<
所需的重载本身就是一个模板:
template<class charT, class traits, class Allocator>
basic_ostream<charT, traits>&
operator<<(basic_ostream<charT, traits>&& os,
const basic_string<charT,traits,Allocator>& str);
为了用于模板参数推导,用户定义的类型必须是精确匹配;转换不被考虑。
您需要为您的班级提供operator<<
的重载,或明确转换为std::string
。
答案 2 :(得分:4)
通常,它取决于类的流插入运算符<<
是具体函数还是模板。
将<<
作为具体函数,找到重载并完成转换(只要它不含糊不清):
#include <iostream>
using namespace std;
template< class CharType >
struct String {};
ostream& operator<<( ostream& stream, String<char> const& s )
{
return (stream << "s");
}
struct MyClass
{
operator String<char> () const { return String<char>(); }
};
int main()
{
cout << "String: " << String<char>() << endl;
cout << "MyClass: " << MyClass() << endl;
}
但是,如果<<
作为函数模板,模板匹配找不到匹配项,则不会尝试通过用户定义的运算符进行转换:
#include <iostream>
using namespace std;
template< class CharType >
struct String
{
};
template< class CharType >
ostream& operator<<( ostream& stream, String< CharType > const& s )
{
return (stream << "s");
}
struct MyClass
{
operator String<char> () const { return String<char>(); }
};
int main()
{
cout << "String: " << String<char>() << endl;
cout << "MyClass: " << MyClass() << endl; // !Oops, nyet! Not found!
}
在您的情况下,std::string
实际上只是typedef
的{{1}}。
修复:为您的类定义std::basic_string<char>
运算符,或者,如果您想避免标头依赖关系(思考构建时间),请定义转换为例如<<
,或者,最简单,我建议将该转换设为一个,以便必须明确调用它。
明确是好的,暗示是坏的。
答案 3 :(得分:0)
我认为您需要覆盖的运算符是“&lt;&lt;”
答案 4 :(得分:0)
您需要覆盖operator<<
方法。
std::ostream & operator <<(std::ostream & os, const Test & t) {
return os << std::string(t);
}