#为 1)中的 Complex 类添加 operator-、operator-=和 operator<<运算符,其中
operator-和 operator<<使用友元函数的方法实现,operator-=使用成员函数的方
法实现。修改后的 Complex 类定义如下。
class Complex{
public:
Complex();
Complex(double r);
Complex(double r, double i);
Complex(const Complex& c);
~Complex();
void setValue(double r, double i);
double getReal() const ;
double getImage() const;
**double getDistance() const;
void output() const;
friend std::ostream& operator<<( std::ostream& out,
const Complex& f);
Complex operator+(const Complex& f)const;
Complex operator*(const Complex& f)const;
Complex & operator+=(const Complex & f);
Complex & operator*=(const Complex & f);
Complex & operator++();//前置++,实部加 1
Complex operator++(int);//后置++,实部加 1
Complex& operator-=(const Complex & f);
friend Complex operator-(const Complex & f1, const Complex & f2);
private:
double real;
double image;
};
在Example1未修改之前, 我们编译器报错为:
error C2784: 'class std::reverse_iterator<`template-parameter-1', `template-parameter-2', `template-parameter-3', `template-parameter-4', `template-parameter-5'> __cdecl std::operator +(template-parameter-5, const class std::reverse_iterator< `template-parameter-1', `template-parameter-2', `template-parameter-3', `template-parameter-4', `template-parameter-5'>&)' : could not deduce template argument for 'template-parameter-5' from 'int'
error C2677: binary '+' : no global operator defined which takes type 'class N::C' (or there is no acceptable conversion)
这虽然是由于没找到operator+的原因导致的 但是编译错误却很奇怪。
类似的, 如果还有一个常见的错误例子是:
#include <iostream>
#include <sstream>
#include <iterator>
#include <vector>
#include <algorithm>
using namespace std ;
namespace skg {
struct Triplet {
int x, y, z ;
Triplet (const int& p_x, const int& p_y, const int& p_z)
: x(p_x), y(p_y), z(p_z) { }
} ;
}
using namespace skg;
ostream& operator<< (ostream& os, const skg::Triplet& p_t) {
os << '(' << p_t.x << ',' << p_t.y << ',' << p_t.z << ')' ;
return os ;
}
void printVector() {
vector< Triplet > vti ;
vti.push_back (Triplet (1, 2, 3)) ;
vti.push_back (Triplet (5, 5, 66)) ;
copy (vti.begin(), vti.end(), ostream_iterator<Triplet> (cout, "\n")) ; // error compile
std::cout << vti[0] << vti[1] << std::endl; // ok
}
int main (void) {
printVector() ;
Triplet t(1, 2, 3);
std::cout << t << std::endl;// ok
}
没有将ostream& operator<< (ostream& os, const skg::Triplet& p_t)放到namespace skg中
编译错误为:
from test68-namespace-overload-cout.cpp:3:
/usr/include/c++/4.8/bits/stream_iterator.h: In instantiation of ‘std::ostream_iterator<_Tp, _CharT, _Traits>& std::ostream_iterator<_Tp, _CharT, _Traits>::operator=(const _Tp&) [with _Tp = skg::Triplet; _CharT = char; _Traits = std::char_traits<char>]’:...
In file included from /usr/include/c++/4.8/iostream:39:0,
from test68-namespace-overload-cout.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 = skg::Triplet]’
operator<<(basic_ostream<_CharT, _Traits>&& __os, const _Tp& __x)
编译错误信息令人费解,原因是匹配到一个错误的operator<<上,但是参数有不能匹配,报错参数错误,如: cannot bind ‘std::ostream_iterator<skg::Triplet>::ostream_type {aka std::basic_ostream<char>}’ lvalue to ‘std::basic_ostream<char>&&’, 但实际是namespace的问题, 新手容易在这里掉坑里。
Ref
http://www.gotw.ca/publications/mill08.htm