user674155
user674155

Reputation:

int p is not a constant expression in lpNorm<p>

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

Answers (3)

kangshiyin
kangshiyin

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

Fantastic Mr Fox
Fantastic Mr Fox

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

Some programmer dude
Some programmer dude

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

Related Questions