我觉得 constexpr 在 C++11 中的用处有限,因为无法定义两个函数,否则它们将具有相同的签名,但一个是 constexpr,另一个不是 constexpr。换句话说,如果我可以拥有一个仅接受 constexpr 参数的 constexpr std::string 构造函数,以及一个用于非 constexpr 参数的非 constexpr std::string 构造函数,那将非常有帮助。另一个例子是理论上复杂的函数,可以通过使用状态来提高效率。你不能用 constexpr 函数轻易做到这一点,所以你有两个选择:如果你传入非 constexpr 参数,则有一个非常慢的 constexpr 函数,或者完全放弃 constexpr (或编写两个单独的函数,但您可能不知道要调用哪个版本)。
因此,我的问题是:
符合标准的 C++11 实现是否有可能允许基于 constexpr 的参数进行函数重载,或者这是否需要更新标准?如果不允许,是不是故意不允许的?
@NicolBolas:假设我有一个将 enum
std::string
函数。 The most straight-forward way to do this, assuming my enum
goes from 0
to n - 1
, is to create an array of size n
充满了结果。
我可以创建一个 static constexpr char const * []
并在返回时构造一个 std::string
(支付创建一个 std::string
对象的成本每次调用该函数),或者我可以创建a static std::string const []
并返回我查找的值,在我第一次调用该函数时支付所有 std::string
构造函数的成本。似乎更好的解决方案是在编译时在内存中创建 std::string
(类似于现在使用 char const *
所做的),但唯一的方法是提醒构造函数它有 constexpr
参数。
对于 std::string
构造函数以外的示例,我认为找到一个示例非常简单,如果您可以忽略 constexpr
的要求(从而创建一个非 constexpr
函数),您可以创建更高效的函数。考虑这个线程: constexpr 问题,为什么这两个不同的程序使用 g++ 在如此不同的时间内运行?
如果我用 constexpr
参数调用 fib
,我无法比编译器完全优化函数调用做得更好。但是,如果我用非 constexpr
参数调用 fib
,我可能想让它调用我自己的版本来实现诸如 memoization 之类的东西(这将需要状态)所以我得到运行时间如果我传递了一个 constexpr
参数,这类似于我的编译时间。
原文由 David Stone 发布,翻译遵循 CC BY-SA 4.0 许可协议
我同意缺少此功能-我也需要它。例子:
现在我必须用模板来做到这一点:
这很好,但我错过了超载的机会。如果我制作了一个库函数供其他人使用,那么用户必须根据 n 是否为编译时间常数来使用不同的函数调用是很不方便的,并且可能难以预测编译器是否已将 n 减少到编译时间常数与否。