Problems with templates

closed account (iw0XoG1T)
This will compile link and run:

link_list.cpp:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>
#include <stdexcept>
#include <Link.h>

using namespace std;

void keep_open()
{
	char ch;
	cout << "enter any character: ";
	cin >> ch;
}

int main(int argc, char* argv[])
{
	Link<string>* odd = new Link<string>("999");
	odd->insert(new Link<string>("997"));
	cout << odd << endl;
	keep_open();
	return 0;
}


Link.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
using namespace std;

template<class T>
class Link
{
public:
	Link<T>(T v, Link<T>* p = 0, Link* s = 0)
		:private_curr(v), prev(p), succ(s){}
	
	Link<T>* insert(Link<T>* li)
	{
		li->succ = this;
		li->prev = prev;
		prev = li;
		return this;
	}

	T curr() {return private_curr;}

private:
	T private_curr;
	Link<T>* prev;
	Link<T>* succ;
};

ostream& operator<<(ostream& os, Link<string>* li);

#endif 


but if I change the header to this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
using namespace std;

template<class T>
class Link
{
public:
	Link<T>(T v, Link<T>* p = 0, Link* s = 0)
		:private_curr(v), prev(p), succ(s){}
	
	Link<T>* insert(Link<T>* li);

	T curr() {return private_curr;}

private:
	T private_curr;
	Link<T>* prev;
	Link<T>* succ;
};

ostream& operator<<(ostream& os, Link<string>* li);

#endif 


and add this soure file (link.cpp):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <Link.h>

using namespace std;

ostream& operator<<(ostream& os, Link<string>* li) {return os << li->curr();}

template<class T>
Link<T>* Link<T>::insert(Link<T>* li)
{
	li->succ = this;
	li->prev = prev;
	prev = li;
	return this;
}


It will compile but not link and this is the message I get:

g++ link.o link_list.o -lstdc++ -o link_test
link_list.o:link_list.cpp:(.text+0x3d4): undefined reference to `Link<std::string>::insert(Link<std::string>*)'


Why can't I define the member function in a separate source file?
Because it's a template. You must have all the templated functions available in the header file on linking.
closed account (iw0XoG1T)
Does this rule apply to all functions or only class member functions, because I seem to be having the same problem with templated functions?
Also if you have to define functions in the header doesn't that make templated functions awkward to use?
It applies to template functions as well.

As for making it awkward to use, no, I would disagree. Make the header file cluttered? Yes.
In that case, you could put the implementations in a file named, say, link.inl, and #include it at
the end of link.h. This keeps the header file neater and satisfies the requirement at the same time.
closed account (iw0XoG1T)
I just ran a test and you were right it is not awkward--I had a misconception about how I could use headers (I am glad I made the statement because I learned something).

As for adding an include at the end that is really clever--it would never have occurred to me--thanks for the tip.
Topic archived. No new replies allowed.