I don't have much experience with C++ template so my terminology might be off. Please bear with me and correction is welcome.
I have generic type fixed_buf<N>
:
// in foo.h
template <int N>
class fixed_buf {
private:
unsigned char data[N];
public:
const unsigned char* begin() const {
return std::begin(data);
}
const unsigned char* end() const {
return std::end(data);
}
};
And I want to define a generic to_hex
function
// in foo.h
template <typename T> std::string to_hex(const T& b);
// in foo.cpp
template <typename T> string to_hex(const T& b) {
string r;
hex(b.begin(), b.end(), back_inserter(r));
return r;
}
Using explicit instantiation I have following as well:
// in foo.cpp
template string to_hex(const vector<unsign char>&);
How should I explicitly instantiate to_hex
with fixed_buf<N>
? Is it possible?
This means to tell the compiler to create a function from the function template with some specified types, even if it might not be needed (e.g. to be able to link against it or to reduce compile times).
A template can be seen as a "type level function". Your to_hex
takes some type as argument and "returns" a function of some type.
to_hex :: T -> to_hex<T>
Your fixed_buf
is also a type level function. It takes some (compile time type level) integer and returns a (structure) type:
fixed_buf :: int(N) -> fixed_buf<N>
You cannot "pass" fixed_buf
to to_hex
; it's not a type but a type level function. You can only pass the result of fixed_buf
. If You don't know what (type level) integer to pass to fixed_buf
then you need to turn this into a (type level) function:
\N -》 to_hex(fixed_buf(N)) :: int(N) -> to_hex<fixed_buf<N>>
Without some specified type level integer this is not a type though; and only types (= completely applied templates in this case) can be instantiated by the compiler.
So you can explicitly instantiate to_hex<fixed_buf<42>>
(this is one function) but not to_hex<fixed_buf<N>>
(a template).
You can explicitly instantiate to_hex<fixed_buf<1>>
, to_hex<fixed_buf<2>>
, ... though; but I don't think that it would be reasonable to do so
If you don't mean instantiate but rather "specialise" then again no, you cannot provide a template specialisation because it would need to be a partial specialization (you don't know N
) and these are not allowed for functions. Solutions:
put the implementation into a template struct
; they can be partially specialised.
Use an overload:
template <int N>
string to_hex(const fixed_buf<N>& b) { /* implementation */ }
This is an overload (not a partial specialisation; these are not allowed for function templates) which should work.