Say I have a template class declared as follows:
template< int *x > struct y { int *b; y() { b = x; }}
I do need the template parameter to be a constant memory address - it is an embedded code. If I try to instantiate it like this: (compiler is gcc 4.8.1 with -std=gnu++11)
y< 1 > c;
I will get an error "could not convert template argument '1' to 'int*'" and that's fine and according to standard. I understand it.
My problem is that casting to pointers does not work either:
y< (int *)1 > d;
y< reinterpret_cast<int *>(1) > e;
error: could not convert template argument '1u' to 'int*'
in both cases. Why is that? Template argument is already converted, isn't it?
This is not allowed as per the C++ standard, section §14.3.2
A template-argument for a non-type, non-template template-parameter shall be one of:
- an integral constant-expression of integral or enumeration type; or
- the name of a non-type template-parameter; or
- the address of an object or function with external linkage, including function templates and function template-ids but excluding non-static class members, expressed as & id-expression where the & is optional if the name refers to a function or array, or if the corresponding template-parameter is a reference; or
- a pointer to member expressed as described in 5.3.1
Solution :
Use a variable with external linkage as the template parameter :
template< int *x > struct y
{
int *b;
y() { b = x; }
};
extern int i; // Extern
static int j = 1; // Static
int z = 1; // Global
int main() {
y< &i > c1;
y< &j > c2;
y< &z > c3;
return 0;
}
Live example here.
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