Let us assume we have a function template which is implemented in the cpp file with help of explicit instantiation like this:
function.h
template<typename T> void function(T val);
function.cpp
#include "function.h"
template<typename T> void function(T val) { /* do something */ }
template void function<double>(double val);
We are now able to call the function in a main file that includes function.h like this:
double val = 1.0;
function(val);
Let us further assume we have a class which is implemented like this:
data.h
class Data
{
private:
double mVal;
public:
Data(double val) { mVal = val; }
operator double () { return mVal; }
};
The following code results in the linker error LNK2019: unresolved external (Visual Studio 2010):
Data a(1.0);
function(a);
We could use one of the following expressions to supply a to function()
function<double>(a);
function(double(a));
...
but why is it not possible to just call function(a)? Does there exist any other solution to achieve that without explicitly instantiating function() with type Data?
why is it not possible to just call
function(a)
?
It is. You're calling it. But remember that function
is declared as:
template<typename T> void function(T val);
so template deduction will deduce function<Data>
. The template deduction doesn't know that elsewhere in the code you only have a definition for function<double>
- it just does deduction. And function<Data>
doesn't have a definition, so it fails to link.
Performing the explicit cast yourself (either function<double>(a)
or function(static_cast<double>(a))
) would be the best solution in my opinion. Explicit is nice. You could additionally write a separate function with all the overloads you actually support and just forward to the function template:
void fwd_function(double v) { function(v); }
void fwd_function(foo v) { function(v); }
void fwd_function(bar v) { function(v); }
fwd_function(a); // now we call function<double> because fwd_function(double )
// is the what we're actually calling