'stringstream'参数顺序问题
'stringstream' argument order trouble
我遇到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..
这两个语句之间的唯一区别是参数顺序。为什么第一个语句失败而第二个语句有效?
不要将您的operator<<
仅限于使用wstringstream
,编写它以使其能够使用任何宽流:
std::wostream& operator <<(std::wostream& sstream, Test const& test)
{
return sstream << test.f;
}
或与任何流(宽或窄):
template<typename CharT, typename TraitsT>
std::basic_ostream<CharT, TraitsT>&
operator <<(std::basic_ostream<CharT, TraitsT>& sstream, Test const& test)
{
return sstream << test.f;
}
简短回答
问题是ss << L"text"
给你的是std::wostream
,而不是std::wstringstream
。
您只为std::wstringstream
创建了一个operator<<
,因此下一个操作(您试图在a
上执行)将失败。
答案很长
当你写类似的东西时
ss << L"text" << a << endl;
您不是在调用一个有四个参数的函数。
事实上,您正在链接多个操作:
((ss << L"text") << a) << endl;
这之所以有效,是因为每个operator<<
操作都返回对原始流对象的引用,因此您可以继续以这种方式链接上的进一步操作。
但是,因为iostreams形成了一个继承层次结构,并且operator<<
适用于任何输出流,所以wstringstream
上操作的返回类型比wstringstream
稍微不那么具体。
事实上,ss << L"text"
的求值结果为wostream&
(wostream
是wstringstream
的基类之一)。引用仍然指向相同的原始流对象。。。但是它有一个基类类型。
因此,涉及a
的第二个操作具有以下活动操作数:
wostream&
(在LHS上)Test
(在RHS上)
但是您没有wostream& operator<<(wostream&, Test const&)
。您只创建了一个wstringstream& operator<<(wstringstream& sstream, Test const& test)
,因此没有匹配项。
因此,事实上,当为宽iostreams创建operator<<
时,您应该使其适用于所有wostream
s(显然没有理由将其限制为wstringstreams
):
wostream& operator<<(wostream& sstream, Test const& test)
{
sstream << test.f;
return sstream;
}
更进一步,为什么要把自己限制在宽阔的溪流中?为什么不是普通的呢?
template<typename CharT, typename TraitsT>
std::basic_ostream<CharT, TraitsT>&
operator<<(std::basic_ostream<CharT, TraitsT>& sstream, Test const& test)
{
sstream << test.f;
return sstream;
}
现在,您将能够正确地将Test
类的对象流式传输到wostream
s、ostream
s及其所有后代中。
- 按字母顺序对C++问题中的子字符串索引进行分区
- 初始化与类类型相同的静态成员(静态初始化顺序问题)
- 堆排序,我无法弄清楚我的代码出了什么问题,输出顺序不正确
- 如何修复关卡顺序遍历问题(二叉树)的无限循环错误
- 函数以相反的顺序输出输入问题,并改进算法以解释相等的数字
- 按顺序打印时遇到问题,二叉树的后顺序等
- 库的链接顺序问题
- 绕过 gcc 中的静态链接顺序问题
- 排序顺序问题
- 对"pthread_key_create"的未定义引用;参数顺序不能解决问题
- C++通过引用修改函数中的结构值(可能存在编译顺序问题)
- 线程内二叉树的插入或顺序遍历有什么问题
- 如何在实践中解决项目编译中链接库的顺序问题
- C++:同时避免静态初始化顺序问题和竞争条件
- 针对C++静态破坏/构建顺序问题的平台特定解决方案
- 关于评价顺序和比较的几个问题
- 同步MPI-2单向通信中的顺序问题
- c++ -构建顺序和依赖问题
- 构造函数解析顺序的问题
- 简单的输入/输出控制台应用程序,不按给定的顺序(结构)打印问题