如何在C++中正确定义模板的流操作符

Ano*_*ous 2 c++ gcc g++ c++11

我已经定义了转换函数fromStringtoString适用于任何类型.它们使用流操作符(<<)(>>).这是代码.

#include <iostream>
#include <fstream>
#include <string>
#include <list>
#include <sstream>
#include <cctype>
using namespace std;

template <class Num1>
struct Foo
{
    Num1 X, Y;
};

template <class T>
string toString( T (a))//////
{
    stringstream ss;
    ss << a;
    return(ss.str());
}

template <class T>
T fromString(const string &str)
{
    stringstream ss(str);
    T result;
    ss>>result;
    return(result);
}

template <class T>
void proc_FromString(const string &str, T (&a))
{
    a = fromString<T>(str);
};

template <class Num>
istream &operator>>(istream &input,Foo<Num> &c)
{
    input>>c.X>>c.Y;
    return input;
};


template <class Num>
ostream &operator<<(ostream &output, Foo<Num> (&c))
{
    output<<"Foo("<<c.X<<","<<c.Y<<")";
    return output;
};

int main(int argNum, char *args[])
{
    Foo<int> fa;
    proc_FromString("1 2",fa);
    int a;
    cout<<toString(a)<<endl;
    cout<<toString(fa)<<endl;
    return(0);
}
Run Code Online (Sandbox Code Playgroud)

有用.但它不是最优的:

template <class T>
string toString( T (a))//////
{
    stringstream ss;
    ss << a;
    return(ss.str());
}
Run Code Online (Sandbox Code Playgroud)

我在函数中复制参数而不是通过引用给出参数.

好.我建议这些更改会使其更好(在代码中重新定义):

#include <iostream>
#include <fstream>
#include <string>
#include <list>
#include <sstream>
#include <cctype>
using namespace std;

template <class Num1>
struct Foo
{
    Num1 X, Y;
};

template <class T>
string toString(const T (&a))////// Redefining there!!!!
{
    stringstream ss;
    ss << a;
    return(ss.str());
}

template <class T>
T fromString(const string &str)
{
    stringstream ss(str);
    T result;
    ss>>result;
    return(result);
}

template <class T>
void proc_FromString(const string &str, T (&a))
{
    a = fromString<T>(str);
};

template <class Num>
istream &operator>>(istream &input,Foo<Num> &c)
{
    input>>c.X>>c.Y;
    return input;
};


template <class Num>
ostream &operator<<(ostream &output, Foo<Num> (&c))
{
    output<<"Foo("<<c.X<<","<<c.Y<<")";
    return output;
};

int main(int argNum, char *args[])
{
    Foo<int> fa;
    proc_FromString("1 2",fa);
    int a;
    cout<<toString(a)<<endl; //This works!
    cout<<toString(fa)<<endl; // This not works!
    return(0);
}
Run Code Online (Sandbox Code Playgroud)

并在我的模板结构上获得编译错误.并且只在我的Foo结构上发生错误.

stud\1mTRPO\labs\v3\experiment\main.cpp||In instantiation of 'std::string toString(const T&) [with T = Foo<int>; std::string = std::basic_string<char>]':|
stud\1mTRPO\labs\v3\experiment\main.cpp|59|required from here|
stud\1mTRPO\labs\v3\experiment\main.cpp|19|error: cannot bind 'std::basic_ostream<char>' lvalue to 'std::basic_ostream<char>&&'|
c:\program files\codeblocks\mingw\bin\..\lib\gcc\mingw32\4.7.1\include\c++\ostream|600|error:   initializing argument 1 of 'std::basic_ostream<_CharT, _Traits>& std::operator<<(std::basic_ostream<_CharT, _Traits>&&, const _Tp&) [with _CharT = char; _Traits = std::char_traits<char>; _Tp = Foo<int>]'|
||=== Build finished: 2 errors, 2 warnings (0 minutes, 1 seconds) ===|
Run Code Online (Sandbox Code Playgroud)

请帮我正确解决这个问题.

我认为原因在于<<运营商没有正确定义.

先感谢您!

Rei*_*ica 5

问题是,你的运营商<<采取c非const引用,所以它不能绑定到const T&中使用toString().像这样更改运算符:

template <class Num>
ostream &operator<< (ostream &output, const Foo<Num> &c)
{
    output<<"Foo("<<c.X<<","<<c.Y<<")";
    return output;
};
Run Code Online (Sandbox Code Playgroud)