Reputation:
I wrote this function
template <typename T>
double norm(const T & v, const int p) {
return v.template lpNorm<p>();
}
but it doesn't work and gives the error:
error: 'p' is not a constant expression
return v.template lpNorm<p>();
^
I seem to think that the compiler expects p
to be known at compile time whereas my p
is dynamic.
Possibly related:
Why is this not a constant expression?
Non-type template argument is not a constant expression
How can I fix this?
Upvotes: 3
Views: 277
Reputation: 9779
You can partially do it with a limited range of p
. For lpNorm
operation it is usually enough.
You've already known that you need a compile-time constant as the template parameter. However as p
is usually used in a small range (0,1,2,inf), you could use the following trick to make it work for a small sub-set of commonly used int
values.
template<typename T>
double norm(const T & v, const int p) {
switch (p) {
case 0:
return v.template lpNorm<0>();
break;
case 1:
return v.template lpNorm<1>();
break;
case 2:
return v.template lpNorm<2>();
break;
case Eigen::Infinity:
return v.template lpNorm<Eigen::Infinity>();
break;
default:
break;
}
}
Upvotes: 3
Reputation: 33944
You cant.
Templates are resolved at compile time. This means for each value of p
in the line lpNorm<p>()
you will generate code specific to that template. If p
can be any value then you need to generate code for every possible value which is not a good idea, the compiler is telling you this.
p
must be known at compile time which means you need to do something like this:
template <int p, typename T>
double norm(const T & v) {
Then specialize for any value of p
that you might expect to receive.
If p
truely is dynamic, then you need a run-time solution, not a compile time solution, so it is likely that you want this:
lpNorm(p);
(you will obviously need to redefine how lpNorm
works)
Upvotes: 3
Reputation: 409432
Templates are resolved at compile-time. And because of that they can't be run-time variables. And despite the const
in the argument declaration p
is still a run-time variable.
The const
in the argument declaration simply means that the function can not change the argument value. It's still possible to call your function with a normal non-constant variable.
Upvotes: 3