Why 'constexpr' parameters are not allowed?

若如初见. 提交于 2021-01-27 01:50:15

问题


It would be useful to have 'constexpr' parameters in order to distinguish compiler-known values and so to be able detecting errors at compile-time. Examples:

int do_something(constexpr int x)
{
  static_assert(x > 0, "x must be > 0");
  return x + 5;
}

int do_something(int x)
{
  if(x > 0) { cout << "x must be > 0" << endl; exit(-1); }
  return x + 5;
}

int var;

do_something(9); //instance 'do_something(constexpr int x)' and check arg validity at compile-time

do_something(0); //produces compiler-error

do_something(var); //instance 'do_something(int x)'

Which is an invalid code for now. Can somebody explains me why this can't be implemented?

EDIT:

Using templates users should assure that literals are always passed as template arguments and not as function ones which is very uncomfortable:

template<int x>
int do_something()
{
  static_assert(x > 0, "x must be > 0");
  return x + 5;
}

int do_something(int x)
{
  if(x > 0) { cout << "x must be > 0" << endl; exit(-1); }
  return x + 5;
}

int var;

do_something(9); //instance 'do_something(int x)' and doesn't checks validity at compile-time

do_something(0); //same as above, if check was performed - compiler error should occur

do_something<9>(); //instance template 'do_something<int>()'

do_something<0>(); //produces compiler error

do_something(var); //instance 'do_something(int x)'

回答1:


If I'm understanding what you're trying to do correctly, the functionality you are requesting is already available. It's not the most elegant, but I think this is good enough.

You would like to call a function at compile-time and run-time with the same syntax, and have it evaluate at compile-time if possible, otherwise it should evaluate at run-time. You need assertions to be evaluated on the function regardless of when it is called.

I believe that this will do what you want:

constexpr int do_something(int x)
{
    if(x <= 0)
    {
        std::cout << "x must be > 0" << std::endl; exit(-1);
    }
    return x + 5;
}

constexpr int compiletime_good = do_something(5);
constexpr int compiletime_bad = do_something(0);    // Fails at compile-time

int runtime_good = do_something(5);
int runtime_bad = do_something(0);    // Fails at runtime

constexpr int val_good = 5;
constexpr int val_bad = 0;

do_something(val_good);
do_something(val_bad);    // Fails at run-time

int valrun_good = 5;
int valrun_bad = 0;

do_something(valrun_good);
do_something(valrun_bad);    // Fails at run-time

The trick here is to fail at compile time in a way that doesn't require static_assert, and will also fail at runtime.




回答2:


While this sounds great in theory, it's not that useful in the real world. Most arguments to functions are not compile time constants, and many constraints are not exactly known at compile time either.

To specify and implement such overloading would be a significant amount of work, and it wouldn't be used that much. When you actually have compile time bounds and arguments, you can usually evaluate the entire function at compile time, which means that overloading is not necessary.



来源:https://stackoverflow.com/questions/27591970/why-constexpr-parameters-are-not-allowed

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