首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >“‘stringstream”参数顺序问题

“‘stringstream”参数顺序问题
EN

Stack Overflow用户
提问于 2011-06-03 01:17:38
回答 2查看 503关注 0票数 2

我遇到了一个关于stringstream的奇怪的问题。

代码语言:javascript
复制
#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;
}

问题出在这里:

代码语言:javascript
复制
ss << L"text" << a << endl; // error C2679!
ss << a << L"text" << endl; // it works well..

这两个语句之间唯一的区别是参数顺序。为什么第一条语句失败,而第二条语句有效?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-06-03 02:10:51

简短的回答

问题是ss << L"text"给了你一个std::wostream,而不是一个std::wstringstream

您只为std::wstringstream创建了一个operator<<,因此下一个操作(您正尝试在a上执行的操作)将失败。

长长的答案

当你写一些像这样的东西

代码语言:javascript
复制
ss << L"text" << a << endl;

您不会调用具有四个参数的函数。

实际上,您正在链接多个操作:

代码语言:javascript
复制
((ss << L"text") << a) << endl;

这是因为每个operator<<操作都会返回一个对原始流对象的引用,这样您就可以继续以这种方式链接进一步的操作。

但是,由于iostreams形成继承层次结构,并且operator<<适用于任何输出流,因此您在wstringstream上的操作的返回类型比wstringstream更具体一些。

实际上,ss << L"text" wostream&的计算结果是一个流引用(wstringstream的基类之一)。引用仍然引用相同的原始流对象……但它有一个基类类型。

因此,涉及a的第二个操作具有以下活动操作数:

  • a wostream& (on the LHS)
  • a Test (on the RHS)

但是你没有wostream& operator<<(wostream&, Test const&)。您只创建了一个wstringstream& operator<<(wstringstream& sstream, Test const& test),所以没有匹配项。

因此,实际上,在为宽iostreams创建operator<<时,您应该使其适用于所有wostream(显然没有理由将其限制为wstringstreams):

代码语言:javascript
复制
wostream& operator<<(wostream& sstream, Test const& test)
{
    sstream << test.f;
    return sstream;
}

为什么不是普通的呢?

代码语言:javascript
复制
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类的对象流式传输到wostreamostream及其所有子对象中。

票数 4
EN

Stack Overflow用户

发布于 2011-06-03 01:21:03

不要将您的operator<<限制为只使用wstringstream,编写它使其可以与任何宽流一起工作:

代码语言:javascript
复制
std::wostream& operator <<(std::wostream& sstream, Test const& test)
{
    return sstream << test.f;
}

或任何小溪(宽的或窄的):

代码语言:javascript
复制
template<typename CharT, typename TraitsT>
std::basic_ostream<CharT, TraitsT>&
operator <<(std::basic_ostream<CharT, TraitsT>& sstream, Test const& test)
{
    return sstream << test.f;
}
票数 9
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6217837

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档