Skupiny Google už nepodporují nová předplatná ani příspěvky Usenet. Historický obsah lze zobrazit stále.

C++ template friend

0 zobrazení
Přeskočit na první nepřečtenou zprávu

Craig Newman

nepřečteno,
7. 5. 2002 13:14:0007.05.02
komu:
I am working through the www.free-ed.net online version of "Teach Yourself
C++ in 21 Days"

In the chapter on templates, several examples are given using the following
friend declaration and implementation. However, I always get link errors
referencing the friend code.

Am I doing something wrong, or is there some problem with the example code?
I've tried this with Borland's command line compiler bcc32, and with GNU's
gpp. Both compilers will compile the code but neither will link it. All the
other examples throughout the course have complied well.

Only the minimal code is show below. The actual program has complete
implementations, a main(), etc.

Thanks in advance for any insights.
- Craig Newman
_____________________________________


template <class T> // declare the template and the parameter
class Array // the class being parameterized
{
public:
// constructors
Array(int itsSize);
Array(const Array &rhs);
~Array() { delete [] pType; }

// operators
Array& operator=(const Array&);
T& operator[](int offSet) { return pType[offSet]; }
const T& operator[](int offSet) const { return pType[offSet]; }

// accessors
int GetSize() const { return itsSize; }

// general-template friend
friend ostream& operator<<(ostream&, Array<T>&);

private:
T *pType;
int itsSize;
};


// implement general-template friend
template <class T>
ostream& operator<<(ostream& output, Array<T>& theArray)
{
for (int i = 0; i<theArray.GetSize(); i++)
output << "[" << i << "] " << theArray[i] << endl; return output;
}

Chris ( Val )

nepřečteno,
7. 5. 2002 15:18:4307.05.02
komu:

"Craig Newman" <cne...@lynda.com> wrote in message
news:udg2g7c...@corp.supernews.com...

| I am working through the www.free-ed.net online version of "Teach Yourself
| C++ in 21 Days"

Hi Craig, some comments follow...

| In the chapter on templates, several examples are given using the following
| friend declaration and implementation. However, I always get link errors
| referencing the friend code.
|
| Am I doing something wrong, or is there some problem with the example code?
| I've tried this with Borland's command line compiler bcc32, and with GNU's
| gpp. Both compilers will compile the code but neither will link it. All the
| other examples throughout the course have complied well.

[snip top of class]

|
| // general-template friend
| friend ostream& operator<<(ostream&, Array<T>&);


// This is a *non* templated friend function, and *not*
// a templated one as you have written ;-).
// In fact, you don't need it to be templated at all, but
// you will have to define it's body, here in the class,
// if you make it *non* templated.

| private:
| T *pType;
| int itsSize;
| };
|
|
| // implement general-template friend
| template <class T>
| ostream& operator<<(ostream& output, Array<T>& theArray)
| {
| for (int i = 0; i<theArray.GetSize(); i++)
| output << "[" << i << "] " << theArray[i] << endl; return output;
| }

The above, is an templated function, and quite different from the friend
declaration within the class. So when you invoke operator '<<' in main(),
it tries to invoke the non templated(friend function declaration), in the
class, but, it cannot find the body for that function, as it hasn't been
defined, well not in a way that the linker can see it ;-), and this is the
most likely cause of your problem.

I have been troubled with an similar problem recently, and found out after
some reading, that there are an couple of choices to get this working.

1. Declare and define the friend function in the class itself(inline),
as an *non* templated function.

OR...

2. If you really need it to be an 'templated function', defined outside
your class, you will need to:

a. Forward declare your class
b. Forward declare the overloaded friend function(this might be specific
to Borland only, I'm not sure), and provide an specialisation, see the
"<>" symbol, in the friend declaration.

I have cut out some of your code, to provide an sample, using the forward
declarations. It compiles and links under Borland Builder 5.0 SP1.

# include <iostream>
using namespace std; // Generic Declaration...

template<class T>
class Array;

template<class T>
ostream& operator << ( ostream& output, const Array<T>& rhs );

template <class T>
class Array
{
public:
Array( int itsSize ) : Size( itsSize ) {}

int GetSize() const { return Size; }

template <class T>
friend ostream& operator << <>( ostream& output, const Array<T>& rhs );

private:
int Size;
};

template <class T>
ostream& operator << ( ostream& output, const Array<T>& rhs )
{
output << rhs.GetSize();

return output;
}


int main()
{
Array<int> A( 5 );
cout << A << endl;

return 0;
}

-- OUTPUT --
5

HTH.
Chris Val


Craig Newman

nepřečteno,
7. 5. 2002 18:30:5107.05.02
komu:

Chris ( Val ) <chri...@bigpond.com.au> wrote in message
news:ab99bv$g3t7t$1...@ID-110726.news.dfncis.de...

___________________________________

Thanks, Chris.

I'm just learning right now, so I'll have to absorb all you've written here.
Much appreciation for your help.

Craig


0 nových zpráv