Topic: problem with template friend ?
Author: bs@alice.att.com (Bjarne Stroustrup)
Date: 7 May 92 19:37:54 GMT Raw View
rmartin@willing.Rational.COM (Bob Martin) writes
> Pardon my ignorance of templates. I can see that this will work, but
> it bothers me that you have defined a template whose implementation is
> specific to stack<class, int>, but whose declaration appears to
> announce that it can handle any class at all.
>
> What am I missing here????
Nothing. Sorry. My mistake.
Author: herman@cs.kuleuven.ac.be (Herman Moons)
Date: Mon, 4 May 1992 11:09:50 GMT Raw View
I'm having some problems with interpreting the definition of templates
as given in the ARM.
question 1:
-----------
is it possible to specify default values for non-type template arguments ?
e.g. template <class T, int size=100> class Stack { ... };
Author: bs@alice.att.com (Bjarne Stroustrup)
Date: 5 May 92 09:57:10 GMT Raw View
herman@cs.kuleuven.ac.be (Herman Moons) writes:
I'm having some problems with interpreting the definition of templates
as given in the ARM.
question 1:
-----------
is it possible to specify default values for non-type template arguments ?
e.g. template <class T, int size=100> class Stack { ... };
>From the syntax specified in ARM p.342 I deduce that it might be possible.
However, the two compilers with template support I have access two differ
in this respect
AT&T cfront 3.01 : does not accept default arguments
Borland C++ 3.0 : considers default arguments ok
***> BC++ is right.
question 2:
-----------
How can you specify friend functions for a template class with non-type
arguments ? According to ARM p.347, function templates may use only type
arguments.
***> You are right.
This would mean that I cannot define friend functions for class templates,
as indicated in the example below:
| 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;
| };
|
|
| // The following is illegal according to ARM, but is really what
| // is needed
| template <class T, int sz>
| ostream& operator<< (ostream& os, stack<T,sz> st)
| {
| for (int i=0; i<st.index; i++)
| os << st.tab[i] << endl;
| return os;
| }
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).
***> 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.
Author: rmartin@willing.Rational.COM (Bob Martin)
Date: 6 May 92 21:46:30 GMT Raw View
bs@alice.att.com (Bjarne Stroustrup) writes:
>#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.
Pardon my ignorance of templates. I can see that this will work, but
it bothers me that you have defined a template whose implementation is
specific to stack<class, int>, but whose declaration appears to
announce that it can handle any class at all.
template <class T> ostream operator<< (ostream& os, T st);
What prevents this declaration from being invoked when I do the
following?
#include <iostream.h>
#include "x.h" /* declaration of class X */
#include "stack.h" /* from the example above */
X myX;
stack<int, 100> myStack;
cout << myStack;
cout << myX;
If we assume that x.h does not declare a valid operator<< for X then
won't the template in stack.h get used to generate an invalid instance
of operator<< for X??
What am I missing here????
--
+---Robert C. Martin---+-RRR---CCC-M-----M-| R.C.M. Consulting |
| rmartin@rational.com |-R--R-C----M-M-M-M-| C++/C/Unix Engineering |
| (Uncle Bob.) |-RRR--C----M--M--M-| OOA/OOD/OOP Training |
+----------------------+-R--R--CCC-M-----M-| Product Design & Devel. |