constexpr 重载

新手上路,请多包涵

相关: 返回 constexpr 的函数无法编译

我觉得 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 许可协议

阅读 645
1 个回答

我同意缺少此功能-我也需要它。例子:

 double pow(double x, int n) {
    // calculate x to the power of n
    return ...
}

static inline double pow (double x, constexpr int n) {
    // a faster implementation is possible when n is a compile time constant
    return ...
}

double myfunction (double a, int b) {
    double x, y;
    x = pow(a, b);  // call version 1 unless b becomes a compile time constant by inlining
    y = pow(a, 5),  // call version 2
    return x + y;
}

现在我必须用模板来做到这一点:

 template <int n>
static inline double pow (double x) {
    // fast implementation of x ^ n, with n a compile time constant
    return ...
}

这很好,但我错过了超载的机会。如果我制作了一个库函数供其他人使用,那么用户必须根据 n 是否为编译时间常数来使用不同的函数调用是很不方便的,并且可能难以预测编译器是否已将 n 减少到编译时间常数与否。

原文由 A Fog 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题