“字符串流”论证顺序麻烦
我在 stringstream
方面遇到了一个奇怪的问题。
#include "stdafx.h"
#include "iostream"
#include "sstream"
using namespace std;
struct Test
{
float f;
};
wstringstream& operator <<( wstringstream& sstream , const Test& test )
{
sstream << test.f;
return sstream;
}
int _tmain(int argc, _TCHAR* argv[])
{
Test a;
a.f = 1.2f;
wstringstream ss;
ss << L"text" << a << endl; // error C2679!
ss << a << L"text" << endl; // it works well..
getchar();
return 0;
}
问题就在这里:
ss << L"text" << a << endl; // error C2679!
ss << a << L"text" << endl; // it works well..
这两个语句之间的唯一区别是参数顺序。为什么第一个语句失败而第二个语句有效?
I'm experiencing a weird problem with stringstream
.
#include "stdafx.h"
#include "iostream"
#include "sstream"
using namespace std;
struct Test
{
float f;
};
wstringstream& operator <<( wstringstream& sstream , const Test& test )
{
sstream << test.f;
return sstream;
}
int _tmain(int argc, _TCHAR* argv[])
{
Test a;
a.f = 1.2f;
wstringstream ss;
ss << L"text" << a << endl; // error C2679!
ss << a << L"text" << endl; // it works well..
getchar();
return 0;
}
The problem is here:
ss << L"text" << a << endl; // error C2679!
ss << a << L"text" << endl; // it works well..
The only difference between these two statements is argument order. Why does the first statement fail whereas the second one works?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
不要将您的
运算符<<
限制为只能与wstringstream
一起使用,编写它以便它可以与任何宽流一起使用:或与任何流(宽或窄)一起使用:
Don't restrict your
operator<<
only to working withwstringstream
, write it so it will work with any wide stream:or with any stream (wide or narrow):
简短回答
问题是 ss << L"text" 为您提供一个
std::wostream
,而不是std::wstringstream
。您仅为
std::wstringstream
创建了一个operator<<
,因此下一个操作(您尝试在a
上执行的操作)失败了。长答案
当您编写类似的内容时,
您不会调用具有四个参数的函数。
事实上,您正在链接多个操作:
这是有效的,因为每个
operator<<
操作都会返回对原始流对象的引用,以便您可以继续以这种方式链接更多操作。但是,由于 iostream 形成继承层次结构,并且
operator<<
适用于任何输出流,因此对wstringstream
操作的返回类型比 wstringstream 稍微不太具体。事实上,
ss << L"text"
计算结果为wostream&
(wostream
是wstringstream
的基类之一)。该引用仍然引用相同的原始流对象...但它具有基类类型。因此,涉及
a
的第二个操作具有以下活动操作数:wostream&
(在左侧)Test
(在右侧)< strong>但是你没有
wostream&运算符<<(wostream&, Test const&)
。您只创建了一个wstringstream&运算符<<(wstringstream& sstream, Test const& test)
,因此没有匹配项。因此,事实上,在为宽 iostream 创建
operator<<
时,您应该使其适用于所有wostream
(显然没有将其限制为wstringstreams
的原因:更进一步,为什么要限制自己使用宽流?为什么不也有普通的呢?
现在,您将能够正确地将
Test
类的对象流式传输到wostream
、ostream
及其所有后代。Short answer
The problem is that
ss << L"text"
gives you astd::wostream
, not astd::wstringstream
.You only created an
operator<<
forstd::wstringstream
, so the next operation (which you're trying to do ona
) fails.Long answer
When you write something like
you are not invoking a function with four arguments.
You are, in fact, chaining multiple operations:
This works because each
operator<<
operation returns a reference to the original stream object, so that you can continue chaining further operations on in this manner.But because iostreams form an inheritance hierarchy, and because
operator<<
is applicable to any output stream, the return type from your operation onwstringstream
is something a little less specific thanwstringstream
.In fact,
ss << L"text"
evaluates to awostream&
(wostream
being one ofwstringstream
's base classes). The reference still refers to the same, original stream object... but it has a base class type.So, your second operation involving
a
has the following active operands:wostream&
(on the LHS)Test
(on the RHS)But you have no
wostream& operator<<(wostream&, Test const&)
. You only created awstringstream& operator<<(wstringstream& sstream, Test const& test)
, so there's no match.So, in fact, when creating an
operator<<
for wide iostreams you should make it work for allwostream
s (clearly there is no reason to limit it towstringstreams
):Going further, why limit yourself to wide streams? Why not normal ones too?
Now you will be able to stream objects of your
Test
class intowostream
s,ostream
s, and all their descendants, properly.