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

家住魔仙堡 提交于 2020-03-22 07:25:30

问题


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?


回答1:


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;
  }
}



回答2:


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.




回答3:


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)



来源:https://stackoverflow.com/questions/38381226/int-p-is-not-a-constant-expression-in-lpnormp

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!