I have a function in TFRuntime.h
class TFRuntime {
...
template <typename T>
Status computeXYSlice(Volume<T>* input, int zCoord, Volume<T> *output);
...
}
TFRuntime.cpp includes tensorflow library headers such as
#include <tensorflow/cc/ops/standard_ops.h>
#include <tensorflow/cc/saved_model/loader.h>
I do not want to make these includes in the header since that would force anyone using TFRuntime to include them as well. However if i want the computeXYSlice
function to allow any type, I have to include the implementation in the .h file. The implementation however requires the above mentioned tensorflow headers.
How do I get around this problem? Could I explicitly 'instantiate' only certain variants of the computeXYSlice
function? E.g., where T
is float
or int
or double
? Or is there a better way?
You cannot define a virtual template method. override only works for virtual methods, and you can only override methods with the same signature.
A non-template class can have template member functions, if required. Notice the syntax. Unlike a member function for a template class, a template member function is just like a free template function but scoped to its containing class.
Defining a Function Template A function template starts with the keyword template followed by template parameter(s) inside <> which is followed by the function definition. In the above code, T is a template argument that accepts different data types ( int , float , etc.), and typename is a keyword.
An explicit specialization of a template is a function, not a template. That function does not become inline just because the template that was specialized is marked with inline . So inline on the template is completely irrelevant.
Could I explicitly 'instantiate' only certain variants of the computeXYSlice function? E.g., where T is float or int or double?
You may, and their implementation need not be in the header. I'll get to that in a moment. But if you really want to allow any type then your template must be in a header. That's just how it is.
If you wish to support only a small set of types, as template instantiations, without overloading (can make a difference sometimes when doing lookup), the standard has a mechanism for explicit template instantiation.
Your header will look something like this...
class TFRuntime {
public:
template <typename T>
Status computeXYSlice(Volume<T>* input, int zCoord, Volume<T> *output);
};
... And your implementation file, will contain the explicit instatiation definitions, like so...
template <typename T>
Status TFRuntime::computeXYSlice(Volume<T>* input, int zCoord, Volume<T> *output) {
// Implement it
}
template
Status TFRuntime::computeXYSlice(Volume<int>*, int, Volume<int>*);
template
Status TFRuntime::computeXYSlice(Volume<double>*, int, Volume<double>*);
You have to include the explicit instantiation definitions, otherwise your program is ill-formed, no diagnostic required. The template function must be defined when implicit instantiation occurs, unless an explicit instantiation appears somewhere.
This is a bit cumbersome. But if your end goal is to indeed have a bunch of instantiations (as opposed to overloads), that's how you tie it all together.
You can wrap the used (non-templated) Tensorflow functionality in your own header/sources file and call your wrappers from your templated code:
// wrapper.h:
void some_function();
// wrapper.cpp:
#include <tensorflow/...>
void some_function() { /* use tensorflow stuff here */ }
// TFRuntime.h:
#include "wrapper.h" // no inclusion of Tensorflow headers involved
template <typename T>
void some_templated_function() {
some_function();
}
Live demo: https://wandbox.org/permlink/dWRT0AEi8alylTQB
However, this solution adds code redundancy and could stop working if Tensorflow API gets changed.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With