我试图重载<

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


如果我在这里错过任何事情或做错了什么,谁能帮助我?

最佳答案

首先,您需要通过添加Currency const& c作为第二个参数来修复运算符(如右图所示)。

然后,您有两个选择:

1:添加朋友

struct Currency
{
  int Dollar;
  int Cents;

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


2:将定义移到类之外

struct Currency
{
  int Dollar;
  int Cents;
};

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


都可以,而且很好。
我个人喜欢option-1,因为它记录了输出运算符与它正在输出的类的紧密耦合。但这是一个简单的案例,任何一个都可以正常工作。

之所以不能成为成员,是因为第一个参数是一个流(运算符的左侧值是第一个参数)。这对成员不起作用,因为第一个参数是隐藏的此参数。因此从技术上讲,您可以将此方法添加到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作为第二个。

关于c++ - 如何在没有 friend 功能的情况下重载<<运算符,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/19550030/

10-11 23:07
查看更多