如何在C++中正确定义模板的流运算符
How to properly define stream operators for templates in C++
我已经定义了转换函数fromString
和toString
来处理任何类型。它们使用流运算符(<<)(>>)。这是代码。
#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);
}
它有效。但它不是很理想:
template <class T>
string toString( T (a))//////
{
stringstream ss;
ss << a;
return(ss.str());
}
我在这里复制函数中的参数,而不是通过引用给出参数。
嗯。我建议这些改变会让它变得更好(在代码中重新定义):
#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);
}
并且在我的模板结构上得到编译错误。错误只发生在我的Foo结构上。
stud1mTRPOlabsv3experimentmain.cpp||In instantiation of 'std::string toString(const T&) [with T = Foo<int>; std::string = std::basic_string<char>]':|
stud1mTRPOlabsv3experimentmain.cpp|59|required from here|
stud1mTRPOlabsv3experimentmain.cpp|19|error: cannot bind 'std::basic_ostream<char>' lvalue to 'std::basic_ostream<char>&&'|
c:program filescodeblocksmingwbin..libgccmingw324.7.1includec++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) ===|
请帮我把它修好。
我认为原因是<<
运算符定义不正确。
提前谢谢!
问题是您的运算符<<
将c
作为非常数引用,因此它无法绑定到toString()
中使用的const T&
。更改操作员如下:
template <class Num>
ostream &operator<< (ostream &output, const Foo<Num> &c)
{
output<<"Foo("<<c.X<<","<<c.Y<<")";
return output;
};
相关文章:
- C++映射:具有自定义类的运算符[]不起作用(总是返回0)
- 有没有一种方法可以通过"typedef"为重新定义的基本类型定义特征和强制转换运算符
- 如何正确实现和访问运算符的各种自定义枚举器
- 自定义先决条件对移动分配运算符有效吗
- 在运算符重载定义中使用成员函数(const错误)
- g++用户定义的动态链接库上的全局new和delete运算符
- 一元"运算符"未在C++中定义
- STL按客户"<"运算符对向量进行排序。为什么要将"<"运算符定义为 const?
- 如何将运算符定义从头文件添加到现有结构?
- 在使用具有相等运算符定义的抽象类时,如何定义父类以减少代码重复?
- 当我们没有将运算符+定义为朋友时?C++
- 没有返回值的c++类成员运算符定义
- 用指向对象的指针和c++中的new运算符定义对象
- <T> 仅为具有运算符/定义的此类 T 创建模板
- 基类中的运算符定义
- C++:不同名称空间中的多个运算符定义
- 运算符定义不能正常工作
- 类运算符'='定义
- 为什么VS不为逻辑运算符定义可选的令牌?
- std::equal_range 不适用于具有运算符<定义的结构