1

so i have this template class:

template<class T = int, unsigned int SIZE =2>
class FixedPoint {
   public:
            explicit FixedPoint(T dollars = 0);
            FixedPoint(T dollars, T cents);

            friend std::ostream& operator<<(std::ostream& os ,const FixedPoint& price);

    private:
        static long digitsAfterDotFactor();
        long sizeAfterDot;
        T dollars;
        T cents;
};

and this is it's definition under the class in the h file

template<class T,unsigned int SIZE>
inline std::ostream& operator<<(std::ostream& os ,const FixedPoint<T,SIZE>& price){
    os << price.dollars << "." << price.cents;
    return os;
}

the code gives me the following error:

friend declaration ‘std::ostream& operator<<(std::ostream&, const FixedPoint<T, SIZE>&)’ declares a non-template function

i tried adding the template name in the decleration but it doesn't recognise T class so what can i do? should i make specification templates for each type ?

songyuanyao
  • 169,198
  • 16
  • 310
  • 405
  • If you want the function definition outside the class definition, change the `friend` declaration to `friend std::ostream& operator<<(std::ostream& os ,const FixedPoint & price)` (i.e. supply the template parameters). I am assuming `` (or, better, ``) is previously included. – Peter Oct 30 '20 at 10:39
  • As a side note: `os << price.dollars << "." << price.cents;` will print 1 dollar and 5 cents as `1.5` and not as `1.05`. – mch Oct 30 '20 at 10:39
  • yeah thank you i know that, i'am just solving one problem at a time lol, compile time errors requires more attention. – Aladin Handoklo Oct 30 '20 at 10:50

2 Answers2

4

As the error message said, the friend declaration declares a non-template operator<<, but it's defined as a template, they don't match.

You can make the friend declaration referring to the operator template, e.g.

// forward declaration
template<class T = int, unsigned int SIZE =2>
class FixedPoint;

// declaration
template<class T,unsigned int SIZE>
std::ostream& operator<<(std::ostream& os ,const FixedPoint<T,SIZE>& price);

template<class T, unsigned int SIZE>
class FixedPoint {
   public:
            ...
            friend std::ostream& operator<< <T, SIZE> (std::ostream& os ,const FixedPoint<T, SIZE>& price);
            // or just
            // friend std::ostream& operator<< <> (std::ostream& os ,const FixedPoint& price);
            ...
};

// definition
template<class T,unsigned int SIZE>
inline std::ostream& operator<<(std::ostream& os ,const FixedPoint<T,SIZE>& price){
    os << price.dollars << "." << price.cents;
    return os;
}
songyuanyao
  • 169,198
  • 16
  • 310
  • 405
  • thanks it worked, but can you explain to me why this happens under the hood – Aladin Handoklo Oct 30 '20 at 10:46
  • @AladinHandoklo You just need to match the `friend` declaration and the defintion of `operator<<`. Non-template vs template won't work, they don't refer to the same thing. – songyuanyao Oct 30 '20 at 10:48
0

You can just define the friend member function within the class template itself,

template<class T = int, unsigned int SIZE =2>
class FixedPoint {
  public:
      /* ... */

      friend std::ostream& operator<<(std::ostream& os ,const FixedPoint& price)
      {
          return os << price.dollars << "." << price.cents;
      }

      /* ... */
};
lubgr
  • 37,368
  • 3
  • 66
  • 117