gpt4 book ai didi

c++ - 为什么我们需要将函数标记为 constexpr?

转载 作者:IT老高 更新时间:2023-10-28 14:00:25 25 4
gpt4 key购买 nike

C++11 允许使用 constexpr 声明的函数用于常量表达式(例如模板参数)的说明符。关于允许的内容有严格的要求 constexpr ;本质上,这样的函数只封装了一个子表达式,没有其他任何内容。 (编辑:这在 C++14 中很放松,但问题仍然存在。)

为什么根本需要关键字? 得到了什么?

它确实有助于揭示界面的意图,但它doesn't通过保证函数在常量表达式中可用来验证该意图。写完后constexpr函数,程序员还必须:

  • 编写测试用例或以其他方式确保它实际用于常量表达式中。
  • 记录在常量表达式上下文中哪些参数值是有效的。

  • 与揭示意图相反,用 constexpr 装饰函数可能会增加一种错误的安全感,因为在忽略中心语义约束的同时检查切向句法约束。

    简而言之:如果 constexpr 是否会对语言产生不良影响?在函数声明中只是可选的?或者对任何有效程序有任何影响吗?

    最佳答案

    防止客户端代码期望超过您的 promise
    假设我正在编写一个库并在其中有一个函数,该函数当前返回一个常量:awesome_lib.hpp :

    inline int f() { return 4; }
    constexpr不是必需的,您 - 作为客户端代码的作者 - 可能会离开并执行以下操作: client_app.cpp :
    #include <awesome_lib.hpp>
    #include <array>

    std::array<int, f()> my_array; // needs CT template arg
    int my_c_array[f()]; // needs CT array dimension
    那我要不要换 f()说从配置文件返回值,您的客户端代码会中断,但我不知道我会冒险破坏您的代码。事实上,可能只有当您遇到一些生产问题并重新编译时,您才会发现这个额外的问题使您的重建工作感到沮丧。
    通过仅更改 f() 的实现,我会有效地改变界面的用途。
    相反,C++11 提供 constexpr所以我可以表示客户端代码可以对剩余的函数有一个合理的期望 constexpr , 并以此方式使用它。我知道并支持将这种用法作为我的界面的一部分。就像在 C++03 中一样,编译器继续保证客户端代码不会被构建为依赖于其他非 constexpr防止上述“不需要/未知依赖”情况的功能;这不仅仅是文档 - 它是编译时强制执行。
    值得注意的是,这延续了 C++ 趋势,即为预处理器宏的传统用途提供更好的替代方案(考虑 #define F 4 ,以及客户端程序员如何知道 lib 程序员是否认为更改说 #define F config["f"] 是公平的游戏),以及他们的好- 已知的“邪恶”,例如在语言的命名空间/类范围系统之外。
    为什么没有对“显然”从不常量函数的诊断?
    我认为这里的困惑是由于 constexpr没有主动确保有任何参数集的结果实际上是编译时常量:相反,它需要程序员对此负责(否则标准中的 §7.1.5/5 认为程序格式错误,但不会不要求编译器发出诊断信息)。是的,这很不幸,但它并没有删除 constexpr 的上述实用程序.
    因此,从问题“ constexpr 的意义何在”转向考虑“为什么我可以编译一个永远不会实际返回 const 值的 constexpr 函数?”也许会有所帮助。
    答:因为需要进行详尽的分支分析,可能涉及任意数量的组合。诊断的编译时间和/或内存成本可能过高——甚至超出了任何可以想象的硬件的能力。此外,即使在实际情况下必须准确诊断此类情况,对于编译器编写者(他们的时间有更好的用途)来说也是一种全新的蠕虫。还会对程序产生影响,例如从 constexpr 中调用的函数的定义。执行验证时需要可见的函数(以及函数调用的函数等)。
    同时,缺少 constexpr继续禁止用作 const 值:严格在 sans- constexpr边。如上所示,这很有用。
    与非`const` 成员函数的比较
  • constexpr防止 int x[f()]而缺少const防止 const X x; x.f(); - 他们都是 确保客户端代码不会硬编码不需要的依赖项
  • 在这两种情况下,您不希望编译器确定 const[expr] -ness 自动 :
  • 您不希望客户端代码在 const 上调用成员函数当您已经可以预期该函数将演变为修改 observable 值,从而破坏客户端代码时
  • 如果您已经预期稍后在运行时确定该值,则您不希望将其用作模板参数或数组维度

  • 他们不同 因为编译器强制执行 const使用 const 内的其他成员成员函数,但不使用 constexpr 强制执行编译时常量结果(由于实际编译器限制)
  • 关于c++ - 为什么我们需要将函数标记为 constexpr?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14472359/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com