C++ 为什么';constexpr';参数是不允许的吗?

C++ 为什么';constexpr';参数是不允许的吗?,c++,language-lawyer,c++14,compile-time,C++,Language Lawyer,C++14,Compile Time,使用“constexpr”参数可以区分编译器已知值,从而能够在编译时检测错误。示例: 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); }

使用“constexpr”参数可以区分编译器已知值,从而能够在编译时检测错误。示例:

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)'
int do\u something(constexpr int x)
{
静态_断言(x>0,“x必须大于0”);
返回x+5;
}
int do_某物(int x)
{

如果(x>0){cout,虽然这在理论上听起来很棒,但在现实世界中并没有那么有用。函数的大多数参数不是编译时常量,许多约束在编译时也不完全知道


指定和实现这种重载需要大量的工作,而且不会用到那么多。当您实际有编译时边界和参数时,通常可以在编译时计算整个函数,这意味着不需要重载。

如果我理解您试图正确执行的操作,您请求的功能已经可用。它不是最优雅的,但我认为这已经足够好了

您希望在编译时和运行时使用相同的语法调用函数,并尽可能在编译时对其求值,否则应在运行时对其求值。无论何时调用函数,都需要对函数求值

我相信这会满足你的要求:

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
constexpr int do_某事(int x)
{

如果(x)你不能用模板?更具体地说是非类型模板参数?那么我的函数的用户应该提供不同的语法来调用它,这取决于参数是否是编译时已知的。如果在.gcc 4.8.3(cygwin x64)中传递了constexpr值,则可能会优化assert()使用-STD= C++ 11不知道使用CONTXPR参数。这是标准吗?我没有经验C++ 14,但是可能是CONTXPRPR是函数的属性,它可以在编译时计算,也可以不计算,这取决于(隐式)。参数的constepr性?
constepr
不是类型限定符。你想要它吗?我们已经有了
const
volatile
,它们一起给出了4种组合。我们真的还需要吗?这并没有明确回答为什么,这就是问题的原因。@cybermonkey我显然不同意。我试图解释一下n为什么该功能不在标准中,通过描述它为什么没有足够的用处来证明所做的努力。与此问题的另一个答案不同,该答案没有以任何方式、形状或形式回答为什么,只是试图描述一种变通方法(即放进实际代码,展示我在第二段中所写的内容)。这将要求在需要“constexpr”的地方调用“do_something”的每个实例,这并不比使用模板好多少。@FISOCPP足够公平。我猜我们没有明确的方法在您询问的方式中包含constexpr参数的原因是,没有人费事编写并推动提案粗略地说。我希望看到这种情况发生,但听起来需要做很多工作。当然,应该使用现有的工具来报告断言失败,而不是Spready
std::exit()
在整个代码库中调用。否则这是非常好的。改进它的唯一方法是,如果参数是编译时常量,即使没有在
constexpr
上下文中运行,也可能会导致编译器警告。可能是整数除以零?
1/(x>0)
当然,编译器是否警告UB是非常特定于编译器的。@BenVoigt谢谢,我只是使用了OP中的代码,所以我使用了他们的运行时失败代码。
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