friend function of templated class

F

Fiber Optic

I wrote a sample app to test using a function to obtain friend-level
access to a templated class. However, I am getting similar errors from
two separate compilers.

If anyone can recommend what function f1() should look like in order
to get it to work I would appreciate it.

Output and code follows.

Chris

$ g++ --version
g++ (GCC) 3.3.1 (cygming special)
$ g++ template.cpp -Wno-non-template-friend
/cygdrive/c/DOCUME~1/<name>/LOCALS~1/Temp/cchYWCO0.o(.text+0x7e):template.
cpp: undefined reference to `f1(Stuff<int, (int)14>&)'
collect2: ld returned 1 exit status

Microsoft Visual Studio .NET 2003
template1 error LNK2019: unresolved external symbol "void __cdecl
f1(class Stuff<int,14> &)" (?f1@@YAXAAV?$Stuff@H$0O@@@@Z) referenced in
function _main

#include <iostream>
using namespace std;

template<class T, int elements> class Stuff;
template<class T, int elements>
void __cdecl f1(Stuff<int, 14> &stuff)
{
cout << "f1() size is " << stuff.size << endl;
}

template<class T, int elements>
class Stuff
{
friend void f1(Stuff<T, elements> &stuff);
public:
Stuff();
int getSize() { return size; }
private:
int size;
};

template<class T, int elements>
Stuff <T, elements>::Stuff()
{
size = elements;
cout << "In Stuff(" << elements << ")" << endl;
}

int main(int argc, char* argv[])
{
Stuff<int, 14> stuff;

cout << "Stuff size is " << stuff.getSize() << endl;

f1(stuff);

return 0;
}
 
I

Ian

Fiber said:
I wrote a sample app to test using a function to obtain friend-level
access to a templated class. However, I am getting similar errors from
two separate compilers.

If anyone can recommend what function f1() should look like in order
to get it to work I would appreciate it.

Output and code follows.

Chris

$ g++ --version
g++ (GCC) 3.3.1 (cygming special)
$ g++ template.cpp -Wno-non-template-friend
/cygdrive/c/DOCUME~1/<name>/LOCALS~1/Temp/cchYWCO0.o(.text+0x7e):template.
cpp: undefined reference to `f1(Stuff<int, (int)14>&)'
collect2: ld returned 1 exit status

Microsoft Visual Studio .NET 2003
template1 error LNK2019: unresolved external symbol "void __cdecl
f1(class Stuff<int,14> &)" (?f1@@YAXAAV?$Stuff@H$0O@@@@Z) referenced in
function _main

#include <iostream>
using namespace std;

template<class T, int elements> class Stuff;
template<class T, int elements>
void __cdecl f1(Stuff<int, 14> &stuff)
try
void f1(Stuff said:
{
cout << "f1() size is " << stuff.size << endl;
}

template<class T, int elements>
class Stuff
{
friend void f1(Stuff<T, elements> &stuff);
try
friend void f1<T, elements>(Stuff &stuff);

Ian
 
V

Victor Bazarov

Fiber said:
I wrote a sample app to test using a function to obtain friend-level
access to a templated class. However, I am getting similar errors from
two separate compilers.

If anyone can recommend what function f1() should look like in order
to get it to work I would appreciate it.

[..]
#include <iostream>
using namespace std;

template<class T, int elements> class Stuff;
template<class T, int elements>

Drop the line above. The 'f1' you're defining here is not a template.
void __cdecl f1(Stuff<int, 14> &stuff)
{
cout << "f1() size is " << stuff.size << endl;

You cannot use 'stuff' here since 'Stuff' hasn't been defined. The body
of this function should be moved below.
}

template<class T, int elements>
class Stuff
{
friend void f1(Stuff<T, elements> &stuff);

Here you're declaring 'f1' as a non-template function.
public:
Stuff();
int getSize() { return size; }
private:
int size;
};

template<class T, int elements>
Stuff <T, elements>::Stuff()
{
size = elements;
cout << "In Stuff(" << elements << ")" << endl;
}

int main(int argc, char* argv[])
{
Stuff<int, 14> stuff;

cout << "Stuff size is " << stuff.getSize() << endl;

f1(stuff);

return 0;
}

This should compile:
----------------------------------------------------
#include <iostream>
using namespace std;

template<class T, int elements> class Stuff;
void f1(Stuff<int, 14> &stuff);

template<class T, int elements>
class Stuff
{
friend void f1(Stuff<T, elements> &stuff);
public:
Stuff();
int getSize() { return size; }
private:
int size;
};

template<class T, int elements>
Stuff <T, elements>::Stuff()
{
size = elements;
cout << "In Stuff(" << elements << ")" << endl;
}

void f1(Stuff<int, 14> &stuff)
{
cout << "f1() size is " << stuff.size << endl;
}

int main(int argc, char* argv[])
{
Stuff<int, 14> stuff;
cout << "Stuff size is " << stuff.getSize() << endl;
f1(stuff);
return 0;
}
 
F

Fiber Optic

Thanks Victor. It compiles just fine.
-Chris

Victor said:
Fiber said:
I wrote a sample app to test using a function to obtain friend-level
access to a templated class. However, I am getting similar errors from
two separate compilers.

If anyone can recommend what function f1() should look like in order
to get it to work I would appreciate it.

[..]
#include <iostream>
using namespace std;

template<class T, int elements> class Stuff;
template<class T, int elements>


Drop the line above. The 'f1' you're defining here is not a template.

void __cdecl f1(Stuff<int, 14> &stuff)
{
cout << "f1() size is " << stuff.size << endl;


You cannot use 'stuff' here since 'Stuff' hasn't been defined. The body
of this function should be moved below.

}

template<class T, int elements>
class Stuff
{
friend void f1(Stuff<T, elements> &stuff);


Here you're declaring 'f1' as a non-template function.

public:
Stuff();
int getSize() { return size; }
private:
int size;
};

template<class T, int elements>
Stuff <T, elements>::Stuff()
{
size = elements;
cout << "In Stuff(" << elements << ")" << endl;
}

int main(int argc, char* argv[])
{
Stuff<int, 14> stuff;

cout << "Stuff size is " << stuff.getSize() << endl;

f1(stuff);

return 0;
}


This should compile:
----------------------------------------------------
#include <iostream>
using namespace std;

template<class T, int elements> class Stuff;
void f1(Stuff<int, 14> &stuff);

template<class T, int elements>
class Stuff
{
friend void f1(Stuff<T, elements> &stuff);
public:
Stuff();
int getSize() { return size; }
private:
int size;
};

template<class T, int elements>
Stuff <T, elements>::Stuff()
{
size = elements;
cout << "In Stuff(" << elements << ")" << endl;
}

void f1(Stuff<int, 14> &stuff)
{
cout << "f1() size is " << stuff.size << endl;
}

int main(int argc, char* argv[])
{
Stuff<int, 14> stuff;
cout << "Stuff size is " << stuff.getSize() << endl;
f1(stuff);
return 0;
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,969
Messages
2,570,161
Members
46,708
Latest member
SherleneF1

Latest Threads

Top