1

Possible Duplicate:
Operator overloading
What causes C++ compiler error: must have argument of class or enumerated type?

I am trying to play a little bit with operator overloading and genericity in C++ and I seem to have 3 little errors when I try to compile. Have a class named Grandeur with template D, and then I inherit 3 classes from this one, named Temps(time), Longueur(size), Vitesse(speed), and I am trying to overload the operators such as when I do Temps+Temps->Temps, Vitesse+Vitesse=Vitesse,Longueur+Longueur->Longueur, Longueur/Time->Vitess etc. In order not to write 3 times the same functions for the operations of same type, I use templates to utilise the genericity. But I have an error when I try to compile. Here is my code:

typedef double Longueur;
typedef double Temps;
typedef double Vitesse;



template<typename D>
class Grandeur {
  protected :
    double val; const char* unite;



  public :
    Grandeur(double qqc) : val(qqc) {}
    Grandeur(int qqc) : val(qqc) {}
    Grandeur(long qqc) : val(qqc) {}
    Grandeur(float qqc) : val(qqc) {}

    inline friend D operator+ (const D a, const D b) {
      return D (a.val + b.val);
    }

    inline friend D operator- (const D a, const D b) {
      return D (a.val - b.val);
    }

    inline friend double operator* (const D a, const D b) {
      return a.val * b.val;
    }

    inline friend double operator/ (const D a, const D b) {
      return a.val / b.val;
    }

    inline friend D operator* (D a, const int b) {
      return D (a.val * b);
    }

    inline friend D operator/ (const D a, const int b) {
      return D (a.val / b);
    }

    inline friend ostream& operator<< (ostream& os, D d) {
      return os << d.val << d.u;
    }

    class Temps : public Grandeur<Temps> {
    public:


  };

  class Vitesse : public Grandeur<Vitesse> {
    public:


  };

  class Longueur : public Grandeur<Longueur> {
    public:

  };

};




inline Longueur operator* (const Vitesse v, const Temps t) {
  return Longueur(v.val * t.val);
}

inline Vitesse operator/ (const Longueur l, const Temps t) {
  return Vitesse(l.val / t.val);
}

inline Temps operator/ (const Longueur l, const Vitesse v) {
  return Temps(l.val / v.val);
}

When I try to compile it says:

g++ essai.cc
In file included from essai.cc:4:0:
grandeurs.h:70:58: error: ‘Longueur operator*(Vitesse, Temps)’ must have an argument of class or enumerated type
grandeurs.h:74:58: error: ‘Vitesse operator/(Longueur, Temps)’ must have an argument of class or enumerated type
grandeurs.h:78:58: error: ‘Temps operator/(Longueur, Vitesse)’ must have an argument of class or enumerated type

The lines 70, 74 and 78 are those with the last 3 functions (the inlines). What can I do?

Community
  • 1
  • 1
André Hincu
  • 427
  • 3
  • 5
  • 13

1 Answers1

1

You're declaring the operators at global scope so the types Vitesse etc are not available to the compiler. Why not move the child classes outside Grandeur<T>'s definition?

EDIT for comment: You're trying to use the operators with double values, but the implicit conversions are not automatically inherited by your child classes. You'll need to define them in each child and pass the parameters up to the parent template class.

Mark B
  • 95,107
  • 10
  • 109
  • 188
  • if i do that i get: grandeurs.h:35:26: error: no matching function for call to ‘Longueur::Longueur(double)’ grandeurs.h:35:26: note: candidates are: grandeurs.h:57:9: note: Longueur::Longueur() grandeurs.h:57:9: note: candidate expects 0 arguments, 1 provided grandeurs.h:57:9: note: Longueur::Longueur(const Longueur&) grandeurs.h:57:9: note: no known conversion for argument 1 from ‘double’ to ‘const Longueur&’ – André Hincu Nov 30 '12 at 21:47