Перегрузка оператора - встроенные функции, не являющиеся членами

Хорошо, я могу заставить свой код работать, но есть кое-что, что меня беспокоит. Это связано с перегрузкой операторов и встроенными функциями, не являющимися членами. Вот очень простая программа, которая реализует объект комплексного числа:

Содержится в Complex.h

using namespace std;

class Complex {
 private:
  double real;
  double imaginary;

 public:

  Complex(void);
  Complex(double r, double i);
  double getReal();
  double getImaginary();
  string toString();
};

inline Complex operator+(Complex lhs, Complex rhs);

... и в Complex.cc

#include <sstream>
#include <string>
#include "Complex.h"

using namespace std;

Complex::Complex(void)
{
...not important...
}

Complex::Complex(double r, double i)
{
  real = r;
  imaginary = i;
}

double Complex::getReal()
{
  return real;
}

double Complex::getImaginary()
{
  return imaginary;
}

string Complex::toString()
{
...what you would expect, not important here...
}


inline Complex operator+(Complex lhs, Complex rhs)
{
  double result_real = lhs.getReal() + rhs.getReal();
  double result_imaginary = lhs.getImaginary() + rhs.getImaginary();

  Complex result(result_real, result_imaginary);

  return(result);
}

и, наконец, в plus_overload_test.cc

using namespace std;

#include <iostream>
#include "Complex.h"

int main(void)
{
  Complex c1(1.0,3.0);
  Complex c2(2.5,-5.2);

  Complex c3 = c1 + c2;

  cout << "c3 is " << c3.toString() << endl;

  return(0);
}

Компиляция с g++ с использованием make-файла, который выполняет связывание, приводит к ошибке:

plus_overload_test.cc:(.text+0x5a): undefined reference to `operator+(Complex, Complex)'

Если я просто уберу "inline" перед оператором + в Complex.h и Complex.cc, то все компилируется и работает как надо. Почему встроенный модификатор вызывает эту ошибку? Все, например:

Перегрузка оператора

а также

http://en.cppreference.com/w/cpp/language/operators

Похоже, что для перегрузки бинарных операторов функции должны быть не-членами и встроенными. Итак, почему я сталкиваюсь с ошибкой, когда я делаю их встроенными?

И да, я понимаю, что встроенный модификатор может быть красной сельдью, поскольку современные компиляторы должны позаботиться об этом. Но я остаюсь любопытным.

Ура!

1 ответ

Решение

inline Функция должна быть определена в каждом файле, где она используется.

В случае, если вы хотите точную формулировку из стандарта (§7.1.2/4):

Встроенная функция должна быть определена в каждой единице перевода, в которой она используется odr, и должна иметь точно такое же определение в каждом случае.

С пометкой inline, но определенная только в одной единице перевода, вы не выполняли свою часть контракта с компилятором (так сказать).

Другие вопросы по тегам