Ambiguous overload of template statements

I am working on two wrapper classes that define real and complex data types. Each class defines overloaded constructors, as well as four arithmetic operators +, -, *, / and five assignment operators =, + =, etc. To avoid code repetition, I was thinking about using template functions when the left and right arguments of the operator have a different data type:

// real.h
class Real {
public:
  explicit Real(const double& argument) {...}
  explicit Real(int argument) {...}
  ...

  friend const operator*(const Real&; const Real&);
  template <class T> friend const Real operator*(const Real&, const T&);
  template <class T> friend const Real operator*(const T&, cont Real&);
  // Here, T is meant to be a template parameter for double and int

  // Repeat for all other arithmetic and assignment operators
};

// complex.h
class Complex {
public:
  explicit Complex(const Real& realPart) {...}
  explicit Complex(const Real& realPart, const Real& imaginaryPart) {...}
  // Overload for double and int data types
  ...

  friend const operator*(const Complex&, const Complex&);
  template <class T> friend const Complex operator*(const Complex&, const T&);
  template <class T> friend const Complex operator*(const T&, cont Complex&);
  // Here, T is is a template parameter for Real, double and int

  ...
};

The problem here is that the code is like:

//main.cpp
void main() {
  Complex ac(2.0, 3.0);
  Real br(2.0);
  Complex cc = ac * br;
}

the compiler ( gcc ) returns an ambiguous overload error for 'operator *' in 'ac * br' , because the compiler cannot determine the difference between:

  • template <class T> friend const Complex operator*(const Complex&, const T&) [with T = Real]
  • template <class T> friend const Real operator*(const T&, cont Real&) [with T = Complex]

, T * Real? ? ?

+2
3

Ah, ...

Boost , , , !

Boost.Operators!

, , , (int double), . ( ), () .

template <typename T>
Complex complex_mult_impl(T const& lhs, Complex const& rhs) { ... } // Note (1)

// return type is not 'Complex const', see (2)
Complex operator*(int lhs, Complex const& rhs)
{ 
  return complex_mult_impl(lhs,rhs);
}

Boost.operators, Complex:: operator * = (int) Complex:: operator * = (double), :)

(1) pass by-value, . Boost.CallTraits, -ref , . .

(2) , const. const - , "" Complex... , !

+2

, Real Complex .

class Real 
{
  ........

  template <class T> const Real operator*(const T&);
  const Real operator*(const Real&);

};
+1

? , *

0

All Articles