如何过载<<操作员无朋友功能 [英] How to overload << operator without friend function

查看:202
本文介绍了如何过载<<操作员无朋友功能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试过载<<操作符打印货币(用户定义类型)

I am trying to overload << operator to print Currency (user defined type)

#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)
     ^

任何人都可以帮助我,如果我错过任何事情或在这里做错了什么?

Can anyone help me if i am missing any thing or doing anything wrong here?

推荐答案

首先,您需要通过添加 Currency const& c 作为第二个参数(因为它在右手边)。

First you need to fix the operator by adding Currency const& c as the second parameter (as it come s on the right hand side).

然后您有两个选项:

struct Currency
{
  int Dollar;
  int Cents;

  friend ostream& operator<< (ostream &out, Currency const& c)
  {
    return out << "(" << c.Dollar << ", " << c.Cents << ")";
  }
};



2:将定义移到类外



2: Move the definition outside the class

struct Currency
{
  int Dollar;
  int Cents;
};

ostream& operator<< (ostream &out, Currency const& c)
{
  return out << "(" << C.Dollar << ", " << c.Cents << ")";
}

工作正常。

选项-1,因为它记录了输出运算符与它正在输出的类的紧耦合。但是这是一个简单的情况,要么工作正常。

Either works and is fine.
Personally I like option-1 as it documents the tight coupling of the output operator to the class that it is outputting. But this is such a simple case that either works just fine.

它不能是成员的原因是第一个参数是一个流(左手边运算符的值是第一个参数)。这对成员不起作用,因为第一个参数是hidden this参数。所以技术上你可以添加这个方法到 std :: ostream 。不幸的是,你没有访问(并且不允许)修改 std :: ostream

The reason that it can not be a member is that the first parameter is a stream (the left hand side value of the operator is the first parameter). This does not work for members as the first parameter is the hidden this parameter. So technically you could add this method to std::ostream. Unfortunately you don't have accesses (and not allowed to) modify std::ostream. As a result you must make it a free standing function.

struct X
{
    std::ostream operator<<(int y)
    {
        return std::cout << y << " -- An int\n";
    }
};
int main()
{
    X   x;
    x << 5;
}


这是因为编译器翻译

That works fine here. This is because the compiler translates

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 作为第二个参数。

Because x has a member function operator<< this works fine. If x did not have a member function called operator<< then the compiler would look for a free standing function that takes two parameters with X as the first and int as the second.

这篇关于如何过载&lt;&lt;操作员无朋友功能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆