problem with templates (?)

M

Matias S

Hello!

I am implementing a dictionary, in C++, for my school assignment. But
when I am testing my Item class (this is what the dictionary is
supposed to store), I get a strange error message from my compiler
(read complainer) g++:

/tmp/ccC63pgw.o: In function `main':
/tmp/ccC63pgw.o(.text+0x43): undefined reference to `Item<int,
::Item[in-charge](int, std::basic_string<char,
std::char_traits<char>, std::allocator<char> >)'
collect2: ld returned 1 exit status

Can you tell me where this subtle, or not so subtle, error is located?
Thanks in advance!

Matias


item.hh:

template<typename KeyType, typename ElemType>
class Item {
public:
Item(KeyType, ElemType);
Item(const Item &);
~Item() { delete _key; delete _elem; }

KeyType *getKey() const { return _key; }
ElemType *getElement() const { return _elem; }

private:
KeyType *_key;
ElemType *_elem;
};

item.cc:

#include "item.hh"

template<typename KeyType, typename ElemType>
Item<KeyType, ElemType>::Item(KeyType k, ElemType e) {
_key = new KeyType(k);
_elem = new ElemType(e);
}

template<typename KeyType, typename ElemType>
Item<KeyType, ElemType>::Item(const Item<KeyType, ElemType> &item) {
_key = new KeyType(*(item.getKey()));
_elem = new ElemType(*(item.getElement()));
}

test.cc:

#include "item.hh"

#include <iostream>
#include <string>

int main() {
Item<int, std::string> anItem(5, "a string");

std::cout << "key " << *(anItem.getKey())
<< "element " << *(anItem.getElement()) << "." <<
std::endl;
return 0;
}
 
L

Leor Zolman

Hello!

I am implementing a dictionary, in C++, for my school assignment. But
when I am testing my Item class (this is what the dictionary is
supposed to store), I get a strange error message from my compiler
(read complainer) g++:

/tmp/ccC63pgw.o: In function `main':
/tmp/ccC63pgw.o(.text+0x43): undefined reference to `Item<int,
::Item[in-charge](int, std::basic_string<char,
std::char_traits<char>, std::allocator<char> >)'
collect2: ld returned 1 exit status

Can you tell me where this subtle, or not so subtle, error is located?
Thanks in advance!
Put your member function templates in the header file. See:

http://www.parashift.com/c++-faq-lite/containers-and-templates.html#faq-34.12
-leor
 
D

Daniel T.

I am implementing a dictionary, in C++, for my school assignment. But
when I am testing my Item class (this is what the dictionary is
supposed to store), I get a strange error message

To fix the error, simply move all the code you have in item.cc into
item.hh. I'm also going to cretique your code in general if you don't
mind.
item.hh:

template<typename KeyType, typename ElemType>
class Item {
public:
Item(KeyType, ElemType);
Item(const Item &);
~Item() { delete _key; delete _elem; }

KeyType *getKey() const { return _key; }
ElemType *getElement() const { return _elem; }

private:
KeyType *_key;
ElemType *_elem;
};
Note, I removed the file break so that the below is now in item.hh
template<typename KeyType, typename ElemType>
Item<KeyType, ElemType>::Item(KeyType k, ElemType e) {
_key = new KeyType(k);
_elem = new ElemType(e);
}

template<typename KeyType, typename ElemType>
Item<KeyType, ElemType>::Item(const Item<KeyType, ElemType> &item) {
_key = new KeyType(*(item.getKey()));
_elem = new ElemType(*(item.getElement()));
}

Why are you holding _key and _elem by pointer? Your code would be
drastically simpler and still correct if you hold them by value.
test.cc:

#include "item.hh"

#include <iostream>
#include <string>

int main() {
Item<int, std::string> anItem(5, "a string");

std::cout << "key " << *(anItem.getKey())
<< "element " << *(anItem.getElement()) << "." <<
std::endl;
return 0;
}

I would suggest you make your expectations explicit in the test code
rather than simply outputing text and hoping the reader of that text (a)
knows what he is looking for and (b) can find it among all the text that
will eventually be output. Something like this would be better:

int main( ) {
string s( "a string" );
Item<int, std::string> anItem( 5, s );

assert( anItem.getKey( ) == 5 );
assert( anItem.getElement( ) == s );

cout << "OK\n";
}

With the above, you can simply add more tests as you build up the class
and you won't get overloaded by heaps of output. If everything works as
expected you will see "OK" if not, the part that didn't work as expected
will be output to the screen.
 
M

Matias S

To fix the error, simply move all the code you have in item.cc into
item.hh. I'm also going to cretique your code in general if you don't
mind.

Not at all. :)
Why are you holding _key and _elem by pointer? Your code would be
drastically simpler and still correct if you hold them by value.

To make sure I got it right: I should instead have
KeyType _key;
ElemType _elem; ?

Thanks for the feedback I got. Now the code compiles.

Matias
 

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

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,584
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top