我正在尝试重载<<运算符以打印货币(用户定义的类型)
#include <iostream>
using namespace std;
struct Currency
{
int Dollar;
int Cents;
ostream& operator<< (ostream &out)
{
out << "(" << Dollar << ", " << Cents << ")";
return out;
}
};
template<typename T>
void DisplayValue(T tValue)
{
cout << tValue << endl;
}
int main() {
Currency c;
c.Dollar = 10;
c.Cents = 54;
DisplayValue(20); // <int>
DisplayValue("This is text"); // <const char*>
DisplayValue(20.4 * 3.14); // <double>
DisplayValue(c); // Works. compiler will be happy now.
return 0;
}
但是收到以下错误。
prog.cpp: In instantiation of ‘void DisplayValue(T) [with T = Currency]’:
prog.cpp:34:16: required from here
prog.cpp:22:9: error: cannot bind ‘std::ostream {aka std::basic_ostream<char>}’ lvalue to ‘std::basic_ostream<char>&&’
cout << tValue << endl;
^
In file included from /usr/include/c++/4.8/iostream:39:0,
from prog.cpp:1:
/usr/include/c++/4.8/ostream:602:5: 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 = Currency]’
operator<<(basic_ostream<_CharT, _Traits>&& __os, const _Tp& __x)
^
如果我在这里遗漏任何事情或做错什么,有人可以帮助我吗?
答案 0 :(得分:8)
你没有把它放进你的课堂,你之后再说。由于您的成员是public
,因此无需将其声明为friend
:
struct Currency
{
int Dollar;
int Cents;
};
ostream& operator<< (ostream &out, const Currency& c)
{
out << "(" << c.Dollar << ", " << c.Cents << ")";
return out;
}
答案 1 :(得分:3)
首先,您需要通过添加Currency const& c
作为第二个参数来修复运算符(因为它位于右侧)。
然后你有两个选择:
struct Currency
{
int Dollar;
int Cents;
friend ostream& operator<< (ostream &out, Currency const& c)
{
return out << "(" << c.Dollar << ", " << c.Cents << ")";
}
};
struct Currency
{
int Dollar;
int Cents;
};
ostream& operator<< (ostream &out, Currency const& c)
{
return out << "(" << C.Dollar << ", " << c.Cents << ")";
}
无论是作品还是罚款 我个人喜欢选项-1,因为它记录了输出操作符与输出类的紧密耦合。但这是一个非常简单的案例,要么工作正常。
它不能是成员的原因是第一个参数是流(操作符的左侧值是第一个参数)。这对成员不起作用,因为第一个参数是隐藏的this参数。从技术上讲,您可以将此方法添加到std::ostream
。很遗憾,您无法访问(并且不允许)修改std::ostream
。因此,你必须使它成为一个独立的功能。
struct X
{
std::ostream operator<<(int y)
{
return std::cout << y << " -- An int\n";
}
};
int main()
{
X x;
x << 5;
}
这在这里工作正常。 这是因为编译器翻译了
x << 5;
进入
// not real code (pseudo thought experiment code).
operator<<(x, 5)
// Equivalent to:
X::operator<<(int y)
// or
operator<<(X& x, int y)
因为x有成员函数operator<<
,所以这很好用。如果x
没有名为operator<<
的成员函数,则编译器会查找一个独立函数,该函数采用两个参数,其中X
为第一个,int
为第二个
答案 2 :(得分:2)
像下面那样重载它,把它放在课堂声明之外(你不需要友谊!):
ostream& operator<< (ostream &out, const Currency &c)
{ //^^^^^^^^^^^^^^^^
out << "(" << c.Dollar << ", " << c.Cents << ")";
return out;
}
你的代码很有趣,你必须使用这样的运算符:
c << cout; // !!
答案 3 :(得分:0)
你编写插入器方法的方法是让它工作的唯一方法是:
c << std::cout;
但相反,如果您知道您的插入器不需要访问任何私有变量,只需按照其他答案说并创建一个带有两个参数的全局函数:
std::ostream& operator <<(std::ostream& os, const Currency& c);
答案 4 :(得分:0)
#include<iostream>
using namespace std;
class node
{
int x;
public:
node()
{
x=0;
}
void operator<<(ostream &vout)
{
vout<<x;
}
friend void operator<<(ostream &vout,node &obj)
{
vout<<x;
}
};
void operator<<(ostream &vout,node &obj)
{
vout<<obj.x;
}
int main()
{
node obj;
cout<<obj;//friend function call
cout<<endl;
obj.operator<<(cout); // overloading the extraction operator without friend
function.
return 0;
}
完全没有必要仅通过使用friend函数来重载插入和提取运算符。 上面的代码在有和没有Friend函数的情况下都使提取运算符过载。之所以喜欢使用朋友函数,是因为可以将cout用于其他数据类型。 类似地,您可以重载插入运算符。
答案 5 :(得分:-2)
你需要把它变成朋友: 你还需要给它正确的参数。 ostream和货币。
friend ostream& operator<< (ostream& stream, const Currency& c )
{
stream << "(" << c.Dollar << ", " << c.Cents << ")";
return stream;
}
修改强>
正如您在评论中看到的那样,您不必将其变为朋友。你可以把它放在结构之外。
Currency c;
c.Dollar = 10;
c.Cents = 54;
DisplayValue(c); // Works. compiler will be happy now.