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
It is not possible to call function(a)
, because then T
will be of type Data
, and not double
, even though it has that conversion operator. And because you are not explicitly defining it in the cpp
file, you get a linker error.
Here are some solutions you could use:
//Call operator double() explicitly
function(a.operator double());
//Specify T
function<double>(a);
//Casting
function(static_cast<double>(a));
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.