Template issue causes linker error (C++)

The answers here are great.

I'll just add that this is often why in addition to .h and .cpp files in a project. You'll often find .inl files. The template definitions will go into the .inl file.

These .inl files mean inline and will usually be included by the .h file of the same name prefix at the bottom of the file after all the header declarations. This effectively makes them part of the header file but separates the declarations from any definitions.

Since they are glorified header files you should take all the same precautions that you would with a regular header file, ie include guards etc.


You are probably suffering from missing a valid instantiation. If you put your template definition in a separate .cpp file, when the compiler compiles that file it may not know which instantiations you need. Conversely, at the call sites which would instantiate the correct version of the template function, if the definition of the function body isn't available the compiler won't have the information to instantiate the required specializations.

You have two options. Put the function body for the function template in the header file.

e.g. in the header file:

template <typename T>
inline T* find_name(std::vector<T*> v, std::string name)
{
    // ...
}

or explicitly instantiate the template in the .cpp where you've defined the template.

e.g. in the source file (will probably require #includeing the file that defines Item):

template <typename T>
T* find_name(std::vector<T*> v, std::string name)
{
    // ...
}

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

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.