【发布时间】:2026-02-24 11:50:01
【问题描述】:
任何只包含 return 语句的函数都可以被声明
constexpr 因此将允许在编译时进行评估,如果所有
参数是constexpr,并且只有constexpr 函数在其主体中被调用。 有什么理由不声明任何这样的功能constexpr?
例子:
constexpr int sum(int x, int y) { return x + y; }
constexpr i = 10;
static_assert(sum(i, 13) == 23, "sum correct");
谁能提供一个声明函数constexpr的例子
会造成什么伤害吗?
一些初步的想法:
即使没有充分的理由去声明一个函数
不是constexpr 我可以想象constexpr 关键字有一个
过渡角色:它在不需要编译时的代码中不存在
评估将允许不实现编译时的编译器
评估仍然编译该代码(但在代码上可靠地失败
这需要它们,通过使用constexpr 进行明确说明。
但我不明白的是:如果没有充分的理由
曾经声明一个函数不是 constexpr,为什么不是 every 函数
在标准库中声明 constexpr? (你不能争论
还没有完成,因为还没有足够的时间
这样做,因为为 all 做这件事是不费吹灰之力的——这与为每个单独的功能决定是否使其成为 constexpr 相反。)
--- 我知道N2976
故意不需要 cstrs 用于许多标准库类型,例如
作为容器,因为这对可能的限制太大了
实施。让我们将它们排除在论点之外,只是想知道:
一旦标准库中的一个类型实际上有一个constexpr cstr,为什么不是每个对其操作的函数都声明为constexpr?
在大多数情况下,您也不能争辩说您可能不喜欢声明函数 constexpr 仅仅是因为您没有设想任何编译时使用:因为如果其他人 evtl.将使用您的代码,他们可能会看到您没有看到的这种用法。 (当然,对于类型特征类型和类似的东西是允许的。)
所以我想故意不声明函数constexpr一定有充分的理由和很好的例子?
(对于“每个功能”,我总是指:满足
要求为constexpr,即定义为单个
return 语句,只接受带有 constexpr 类型的参数
cstrs 并仅调用 constexpr 函数。由于 C++14,much more is allowed in the body of such function:例如,C++14 constexpr 函数可以使用局部变量和循环,因此可以声明更广泛的函数类constexpr。)
问题Why does std::forward discard constexpr-ness? 是这个问题的一个特例。
【问题讨论】:
-
我的问题是:声明为 constexpr 但调用时不会导致常量表达式的函数会发生什么,应该是编译错误不是吗?那么对于那些不是特别旨在仅在编译时进行评估的函数,它们不应该被声明为 constexpr 吗?
-
我搜索了标准并且找不到关于如果 constexpr 函数被非常量表达式参数调用会发生什么的提示。无论如何,如果这是错误的,那么 std::forward 的情况也很清楚,如果你定义了 std::forward constexpr,那么它必须用作 constexpr 并且不能转发普通变量。
-
@user534498 我也找不到标准中的位置。但是唯一有意义的事情(以及 g++ 的实际作用)是在使用非 constexp 参数调用
constexpr函数时默默地忽略constexpr。否则,std::bitset中的size之类的函数显然无法成为constexpr。 -
@Lars:不仅如此,我还注意到,如果 输出 不是明确的
constexpr,g++ 会忽略constexpr,无论输入是否是。虽然我不确定这是否是标准的意图,但这对我来说没有任何意义。例如,将constexpr函数的返回值分配给const int将导致该函数出现在二进制文件中并被执行,而将其分配给enum(具有相同的输入!)只是定义了一个枚举值和根本不生成代码。
标签: c++ c++11 constants constexpr function-declaration