鱼C论坛

 找回密码
 立即注册
查看: 2274|回复: 1

请教大神关于类模板和重载运算符的问题

[复制链接]
发表于 2019-7-5 23:10:00 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
我首先重载了一个加号运算符 程序运行起来没问题 但是按同样的方法重载一个输出运算符就报错 这是为什么??
  1. #include<iostream>
  2. #include<string>

  3. //  在类定义的前面声明模板函数
  4. template<class  T>
  5. void  Show_A( T & a);

  6. template<class T>
  7. T  operator+( T &a1 , T &a2);

  8. template<class T>                                                                             //声明这条语句后 就报错
  9. std::ostream & operator<<(std::ostream & os , const T & a1);


  10. template<class  T>
  11. class  A
  12. {
  13. private:
  14.     T  my_x;
  15.     T  my_y;
  16. public:

  17.     A(T x=0 , T y=0)    :   my_x(x) , my_y(y)       {  std::cout<<"**********构造函数**********\n"; }
  18.     ~A()                                            {  std::cout<<"**********析构函数**********\n"; }

  19.     A(const A & a);                                  //  复制构造
  20.     A & operator=(const A & a);                      //  重载赋值运算符

  21. //  在类里面再次声明友元函数  其参数是类模板类型
  22.     friend void Show_A< A<T> >( A<T> & a );

  23.     friend  A<T>  operator+< A<T> >( A<T> & a1 , A<T> & a2);

  24.     friend  std::ostream & operator<<< A<T> >(std::ostream & os , A<T> &a1);




  25. };


  26. int main()
  27. {
  28.     A<double>  a1(11.5 , 15.5);

  29.     Show_A(a1);





  30.     return 0;
  31. }

  32. template<class T>
  33. std::ostream & operator<<(std::ostream & os , T a1)
  34. {
  35.     os<<"( "<<a1.my_x<<" , "<<a1.my_y<<"! )\n";

  36.     return os;
  37. }

  38. template<class T>
  39. T  operator+( T &a1 , T &a2)
  40. {
  41.     T temp;

  42.     temp.my_x = a1.my_x+a2.my_x;
  43.     temp.my_y = a1.my_y+a2.my_y;

  44.     return temp;
  45. }

  46. //  定义函数模板
  47. template<class  T>
  48. void Show_A(T & a)
  49. {
  50.     std::cout<<"( "<<a.my_x<<" , "<<a.my_y<<"! )\n";

  51. }


  52. template<class T>
  53. A<T> & A<T>::operator=(const A & a)
  54. {
  55.     my_x = a.my_x;
  56.     my_y = a.my_y;

  57.     std::cout<<"**********重载赋值运算符**********\n";
  58.     return *this;
  59. }

  60. template<class T>
  61. A<T>::A(const A & a)              //  复制构造
  62. {
  63.     my_x = a.my_x;
  64.     my_y = a.my_y;

  65.     std::cout<<"**********复制构造函数**********\n";
  66. }
复制代码


请大神帮忙看看
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2019-7-5 23:57:30 | 显示全部楼层
首先,“<<”和“>>”本质上是位运算符,
其之所以能作为流输出输入运算符,是因为在istream和ostream中对其已经进行了重载:
  1. template<class _Elem,
  2.         class _Traits> inline
  3.         basic_istream<_Elem, _Traits>& operator>>(
  4.                 basic_istream<_Elem, _Traits>& _Istr, _Elem *_Str)
  5.         {        // extract NTBS
  6.         typedef basic_istream<_Elem, _Traits> _Myis;
  7.         typedef ctype<_Elem> _Ctype;
  8.         ios_base::iostate _State = ios_base::goodbit;
  9.         _Elem *_Str0 = _Str;
  10.         const typename _Myis::sentry _Ok(_Istr);

  11.         if (_Ok)
  12.                 {        // state okay, extract characters
  13.                 const _Ctype& _Ctype_fac = _STD use_facet<_Ctype>(_Istr.getloc());

  14.                 _TRY_IO_BEGIN
  15.                 streamsize _Count = 0 < _Istr.width() ? _Istr.width()
  16.                         : (numeric_limits<streamsize>::max)();
  17.                 typename _Myis::int_type _Meta = _Istr.rdbuf()->sgetc();
  18.                 _Elem _Ch;
  19.                 for (; 0 < --_Count; _Meta = _Istr.rdbuf()->snextc())
  20.                         if (_Traits::eq_int_type(_Traits::eof(), _Meta))
  21.                                 {        // end of file, quit
  22.                                 _State |= ios_base::eofbit;
  23.                                 break;
  24.                                 }
  25.                         else if (_Ctype_fac.is(_Ctype::space,
  26.                                 _Ch = _Traits::to_char_type(_Meta))
  27.                                         || _Ch == _Elem())
  28.                                 break;        // whitespace or nul, quit
  29.                         else
  30.                                 *_Str++ = _Traits::to_char_type(_Meta);        // add it to string
  31.                 _CATCH_IO_(_Istr)
  32.                 }

  33.         *_Str = _Elem();        // add terminating null character
  34.         _Istr.width(0);
  35.         _Istr.setstate(_Str == _Str0 ? _State | ios_base::failbit : _State);
  36.         return (_Istr);
  37.         }
复制代码
  1. template<class _Traits> inline
  2.         basic_ostream<char, _Traits>& operator<<(
  3.                 basic_ostream<char, _Traits>& _Ostr,
  4.                 const char *_Val)
  5.         {        // insert NTBS into char stream
  6.         typedef char _Elem;
  7.         typedef basic_ostream<_Elem, _Traits> _Myos;
  8.         ios_base::iostate _State = ios_base::goodbit;
  9.         streamsize _Count = (streamsize)_Traits::length(_Val);        // may overflow
  10.         streamsize _Pad = _Ostr.width() <= 0 || _Ostr.width() <= _Count
  11.                 ? 0 : _Ostr.width() - _Count;
  12.         const typename _Myos::sentry _Ok(_Ostr);

  13.         if (!_Ok)
  14.                 _State |= ios_base::badbit;
  15.         else
  16.                 {        // state okay, insert
  17.                 _TRY_IO_BEGIN
  18.                 if ((_Ostr.flags() & ios_base::adjustfield) != ios_base::left)
  19.                         for (; 0 < _Pad; --_Pad)        // pad on left
  20.                                 if (_Traits::eq_int_type(_Traits::eof(),
  21.                                         _Ostr.rdbuf()->sputc(_Ostr.fill())))
  22.                                         {        // insertion failed, quit
  23.                                         _State |= ios_base::badbit;
  24.                                         break;
  25.                                         }

  26.                 if (_State == ios_base::goodbit
  27.                         && _Ostr.rdbuf()->sputn(_Val, _Count) != _Count)
  28.                         _State |= ios_base::badbit;

  29.                 if (_State == ios_base::goodbit)
  30.                         for (; 0 < _Pad; --_Pad)        // pad on right
  31.                                 if (_Traits::eq_int_type(_Traits::eof(),
  32.                                         _Ostr.rdbuf()->sputc(_Ostr.fill())))
  33.                                         {        // insertion failed, quit
  34.                                         _State |= ios_base::badbit;
  35.                                         break;
  36.                                         }
  37.                 _Ostr.width(0);
  38.                 _CATCH_IO_(_Ostr)
  39.                 }

  40.         _Ostr.setstate(_State);
  41.         return (_Ostr);
  42.         }
复制代码

而你用不同的方式再次重载了这个符号,对于同一个运算,编译器能够找到不止一个能匹配的重载函数,就会出现定义不明确的错误
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-5-23 14:39

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表