'stringstream'参数命令麻烦

时间:2011-06-02 17:17:38

标签: c++ visual-studio stringstream visual-studio-2008-sp1

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..

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

2 个答案:

答案 0 :(得分:9)

请勿将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;
}

答案 1 :(得分:4)

简短回答

问题在于ss << L"text"为您提供了std::wostream,而不是std::wstringstream

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

长答案

当你写

之类的东西时
ss << L"text" << a << endl;

你没有调用带有四个参数的函数。

事实上,你正在链接多个操作:

((ss << L"text") << a) << endl;

这是有效的,因为每个operator<<操作都返回对原始流对象的引用,因此您可以继续以这种方式进行进一步的操作。

但是因为iostream构成了一个继承层次结构,并且因为operator<<适用于任何输出流,所以wstringstream上的操作的返回类型稍微不那么具体比wstringstream

事实上, ss << L"text"评估为wostream& wostreamwstringstream基类之一。引用仍引用相同的原始流对象......但它具有基类类型。

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

  • a wostream&(在LHS上)
  • a Test(在RHS上)

但是你没有wostream& operator<<(wostream&, Test const&)。您只创建了wstringstream& operator<<(wstringstream& sstream, Test const& test),因此无法匹配。

因此,实际上,在为广泛的iostream创建operator<<时,您应该让它适用于所有 wostream(显然没有理由将其限制为{ {1}}):

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 s,wostream及其所有后代。

相关问题