Topic: Problem with template friend ?


Author: herman@cs.kuleuven.ac.be (Herman Moons)
Date: Wed, 6 May 1992 16:08:32 GMT
Raw View
*** stuff deleted ***

>> question is about how to specify a friend for a class with non-type
>> template arguments.
>>
>> template <class T, int sz>
>> class stack {
>>     friend ostream& operator<< (ostream& os, stack<T,sz>);
>> ...
>>};
>>
>>Correct me if I'm wrong, but it seems to me that one cannot specify (in
>>generic terms) the type of the stack in the friend function. Is there a
>>work-around for this kind of friend functions (after all, overloading the
>>output operator is not that special, and I would expect that it should be
>>possible to do this).
>>
>>
>>>> bs@alice.att.com (Bjarne Stroustrup) writes:
>>>>
>>>> ***> This conclusion is wrong. Look at your friend declaration and consider
>>>>  what the matching function should look like. Then try this:
>>>>
>>>> #include<iostream.h>
>>>>      template <class T, int sz>
>>>>     class stack {
>>>>          friend ostream& operator<< (ostream& os, stack<T,sz>);
>>>>      public:
>>>>          stack () { index = 0; }
>>>>          void push (T elem) { tab[index++] = elem; }
>>>>          T pop (void) { return tab[--index]; }
>>>>      private:
>>>>          T tab[sz];
>>>>          int index;
>>>>      };
>>>>
>>>>      template <class T>
>>>>      ostream& operator<< (ostream& os, T st)
>>>>      {
>>>>          for (int i=0; i<st.index; i++)
>>>>            os << st.tab[i] << endl;
>>>>          return os;
>>>>      }
>>>>
>>>> It works.

Hm, I tried to run the proposed solution with AT&T cfront 3.0.1, with the
following main program:

    main () {
        stack<int,100> s1;
        s1.push(100);
        cout << s1;
    }

and got the following nasty error message:

    "stack.c", line 36: internal <<AT&T USL C++ Language System <3.0.1>
    02/03/92>> error: bus error (or something nasty like that)
    1 error

The line number refers to the "cout << s1" statement.

Furthermore, I don't see how the proposed solution would work if I have, say,
an additional Queue class, as follows:

    template <class T, int sz>
    class queue {
        friend ostream& operator<< (ostream& os, queue<T,sz>);
       ...
    };

I don't see how the compiler can see the difference between the output
operators for queue and stack, if these are defined in terms of a generic
type T. According to me, the proposed solution defines a catch-all operator<<
function, which, when instantiated, will mostly generate compile errors (since
it was really meant for a stack only).
Any comments ?