Template issue causes linker error (C++)

marsolk picture marsolk · Oct 28, 2009 · Viewed 39.4k times · Source

I have very little idea what's going in regards to C++ templates, but I'm trying to implement a function that searches a vector for an element satisfying a given property (in this case, searching for one with the name given). My declaration in my .h file is as follows:

template <typename T>
T* find_name(std::vector<T*> v, std::string name);

When I compile, I get this linker error when I call the function:

Error   1   error LNK2019: unresolved external symbol "class Item * __cdecl find_name<class Item>(class std::vector<class Item *,class std::allocator<class Item *> >,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >)" (??$find_name@VItem@@@@YAPAVItem@@V?$vector@PAVItem@@V?$allocator@PAVItem@@@std@@@std@@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@@Z) referenced in function "public: class Item * __thiscall Place::get_item(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >)" (?get_item@Place@@QAEPAVItem@@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z) place.obj   Program2

Again, I'm new to templates so I don't know what's going. All instances I've found of LNK2019 through Google have been about not using the correct libraries, but since this is my own function I don't see why this would be happening.

Also, a related question: Is there a way to make a template parameter so that it has to be a subclass of a certain class, i.e. template?

Answer

GManNickG picture GManNickG · Oct 28, 2009

You have to have your template definitions available at the calling site. That means no .cpp files.

The reason is templates cannot be compiled. Think of functions as cookies, and the compiler is an oven.

Templates are only a cookie cutter, because they don't know what type of cookie they are. It only tells the compiler how to make the function when given a type, but in itself, it can't be used because there is no concrete type being operated on. You can't cook a cookie cutter. Only when you have the tasty cookie dough ready (i.e., given the compiler the dough [type])) can you cut the cookie and cook it.

Likewise, only when you actually use the template with a certain type can the compiler generate the actual function, and compile it. It can't do this, however, if the template definition is missing. You have to move it into the header file, so the caller of the function can make the cookie.