Wednesday, October 25, 2006

Specialised Function Template Linking Problem (Multiple Definition)

Imagine a scenario where you have this specialised template implementation, where it converts the first argument to string and place it on second argument. It also indicates the conversion is successful or not.

template< typename T >
bool convertToString(T x, std::string& result)
{
...
}

// As there's no point of converting a string to another string
template<>
bool convertToString(std::string x, std::string& result)
{
...
}

There're perfectly nothing wrong with that when you're using this function template within your class, i.e.
string a_string, out;
f< std::string >(a_string, out));
f(a_string, out); // this will also trigger the specialised template function

However, in most cases, you'll be using these templates on other classes by #include-ing it. All of a sudden, it gives you an error message "Linked error in function XXX: multiple definition of `bool convertToString ... at line YYY". (this error message has been polished for your readability)

Now you're scratching your head, and ask what've gone wrong here? Fret not, take a step back, all the reasoning behind it is that the compiler linker can't decide on which one to choose as both functions DO support std::string. From outside word, this so-called smart tempate functions library just have two SAME functions with the same number argument and the same return type. We need to tell this picky compiler on which one he should be using.

Enough the description, all we need to do is just inlining the specialised template, which essentially tell the compiler that this should be the one you should looked at if it there's multiple definition for it, i.e.

template<>
inline bool convertToString(std::string x, std::string& out)
{
...
}

Problems gone!