constexpr 函数内的 if 与 if constexpr

2024-01-24

最近修改了一些if constexpr into if在我的 constexpr 函数中,发现它们仍然可以正常工作并且可以在编译时进行评估。这是一个最小的情况:

template<int N>
constexpr bool is_negative()
{
    if constexpr  (N >= 0) return false;
    else  return true; 
}
int main()
{
    constexpr  bool v = is_negative<1>();
}

live demo https://godbolt.org/z/4cv0Es

在上述情况下,N必须在编译时知道,因为它是非类型模板参数,所以if constexpr在这里工作得很好。然而,它是一个 constexpr 函数,所以,iirc,它是possible即使我替换也能获得返回值if constexpr with if:

template<int N>
constexpr bool is_negative()
{
    if  (N >= 0) return false;
    else  return true; 
}
int main()
{
    constexpr  bool v = is_negative<1>();
}

live demo https://godbolt.org/z/rcUXvS

From cppref https://en.cppreference.com/w/cpp/language/constexpr, 中的所有要求A constexpr function must satisfy the following requirements:别提if。因此,IIUC,constexpr 函数是否包含应该是实现定义的行为if即使所有相关变量在编译时已知(例如is_negative above).

所以,我的结论是:

  • 在 c++17 之前,我们没有if constexpr,所以选择是if,这意味着不能保证您的 constexpr 函数在编译时得到评估,全部取决于编译器实现
  • 在c++17之后,if constexpr如果我们希望 constexpr 函数在编译时求值,则首选。

以上是我的个人想法,可能有一些重要的遗漏/误解,欢迎指正。问题依然没有改变:if and if constexpr,对于希望在编译时求值的 constexpr 函数应该首选它。

参考: -constexpr 函数中允许什么? https://stackoverflow.com/questions/41618576/what-is-allowed-in-a-constexpr-function - “if constexpr()”与“if()”之间的区别 https://stackoverflow.com/questions/43434491/difference-between-if-constexpr-vs-if


在c++17之前,我们没有if constexpr,所以选择的是if,这意味着不能保证我们的constexpr函数在编译时得到评估,一切都取决于编译器的实现

if 语句不是 constexpr 这一事实并不意味着它不能在编译时作为 constexpr 表达式的一部分进行计算。在你的例子中,v在这两种情况下都会在编译时求值,因为它必须是:它是一个常量表达式。这不是实现定义的。

在 c++17 之后,如果我们希望 constexpr 函数在编译时求值,则首选 constexpr。

Constexpr if 语句的引入是为了解决问题。让 constexpr 函数在编译时求值并不是这个问题。

这是一个示例,其中constexpr if是必需的而不是简单的if(取自参考参数 https://en.cppreference.com/w/cpp/language/if):

template <typename T>
auto get_value(T t) {
    if constexpr(std::is_pointer_v<T>)
        return *t; // deduces return type to int for T = int*
    else
        return t;  // deduces return type to int for T = int
}

尝试删除constexpr关键字并看看会发生什么(demo http://coliru.stacked-crooked.com/a/db1f05c4410783f8).

另请注意,您始终可以使用其他方法解决该问题,但是if constexpr具有简洁的优点。例如,这是一个等价的get_value使用标签调度:

template<typename T>
auto get_value_impl(T t, std::true_type) {
    return *t;
}
template<typename T>
auto get_value_impl(T t, std::false_type) {
    return t;
}

template<typename T>
auto get_value(T t) {
    return get_value_impl(t, std::is_pointer<T>{});
}

Demo http://coliru.stacked-crooked.com/a/fe2e23a57d6c8312

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

constexpr 函数内的 if 与 if constexpr 的相关文章

随机推荐

  • JSON 发布,我是否把 JSON 推得太远了?

    我只是想知道我是否把 JSON 推得太远了 如果有人以前打过这个 我有一个 xml 文件
  • 在 Spark Scala 中将时间戳转换为 UTC

    我的环境是Spark 2 1 Scala 这可能很简单 但我很伤脑筋 我的数据框 myDF 如下所示 orign timestamp origin timezone 2018 05 03T14 56 America St Johns 201
  • elasticsearch_dsl:聚合生成多个桶

    我想生成这个 GET packets 2017 09 25 search size 0 query match transport protocol tcp aggs clients terms field layers ip src ke
  • Excel宏来合并数据

    我的一个文件夹中有很多excel文件 我想要一个宏来遍历每个文件并复制名为最终成本并在目标文件中制作一个带有源文件名称的工作表 就像有三个文件 A B C 每个文件都有一个名为 最终成本 新文件将包含三个工作表 名称为 A B C 编辑后的
  • Bloc 7.2 迁移 - 在流内传递参数

    我目前正在将一个项目从 Bloc 7 0 迁移到 bloc 7 2 我曾经有一个流 我会yield 在不同的流中并每次传递不同的值作为参数 Stream
  • 什么是 BEM 方法? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我最近听说了 BEM 方法 BEM 方法到底有什么用途 BEM 在哪些方面让我们的工作变得更轻松 使用 BEM 是一个好的做法吗 BE
  • Rails3 中的 Ajax 回调

    在rails 2中 对于ajax表单 我们可以有ajax回调 例如之前 之后等 如何在rails 3中做到这一点 我也有同样的问题 并且这个帖子 http blancer com tutorials 105318 using unobtru
  • 将 BigQuery 数据导出为 CSV,而不使用 Google Cloud Storage

    我目前正在编写一个软件 用于导出大量 BigQuery 数据并将查询结果存储为本地 CSV 文件 我使用的是Python 3和google提供的客户端 我进行了配置和身份验证 但问题是 我无法在本地存储数据 每次我执行时 我都会跟随错误信息
  • 轮询成功,但出现错误:操作正在进行中 (29)。当 Xdebug 尝试从 docker 容器连接到 PhpStorm 时

    我正在尝试调试 CLI 脚本 但 Xdebug 无法连接到 PhpStorm 我看到错误Operation now in progress 29 在 Xdebug 远程日志中 我确信 Xdebug 配置正确 但我不知道如何调试 PhpSto
  • 如何删除焦点输入的默认值

    我有一个输入框 分配有默认值文本 当用户聚焦于该字段时 如何删除此文本 CoDE
  • 如何在python中随机化图像像素

    我对计算视觉和Python很陌生 我无法真正弄清楚出了什么问题 我尝试随机化 RGB 图像中的所有图像像素 但结果证明我的图像完全错误 如下所示 有人可以解释一下吗 from scipy import misc import numpy a
  • IIS7 部署 - 重复的“system.web.extensions/scripting/scriptResourceHandler”部分

    尝试在 IIS7 中的默认应用程序池 框架部分设置为 4 0 上部署 net 3 5 网站时 出现以下错误 有一个重复的 system web extensions scripting scriptResourceHandler 部分 定义
  • go 1.5 跟踪命令

    Go 1 5 发行说明说 新的 go tool trace 命令可以实现运行时中新跟踪基础设施生成的程序跟踪的可视化 这真的很令人兴奋 我想了解更多 但其官方文件位于https golang org cmd trace https gola
  • QAbstractTableModel 并为单行发出 dataChanged

    我从 QAbstractTableModel 派生了一个模型 现在我想通知 整行的数据已更改 例如 如果索引为 5 的行的数据发生更改 4 列 则使用以下代码可以按预期工作 emit dataChanged index 5 0 index
  • 钥匙串上的分发证书中缺少私钥

    我遇到以下问题 在任何地方都找不到解决方案 基本上 我们有一个公司开发人员帐户 不是企业 因此为了提交我们的应用程序 我要求我们的团队负责人向我发送分发证书 并创建并向我发送分发配置文件 使用开发人员配置文件 一切正常 但是当我安装证书和配
  • newtype 如何帮助隐藏任何东西?

    现实世界哈斯克尔说 我们将使用新类型隐藏解析器类型的详细信息 宣言 我不明白如何使用新类型隐藏任何内容 谁能详细说明一下吗 我们想要隐藏什么以及我们如何做到这一点 data ParseState ParseState string L By
  • 可可 NSNumberFormatterCurrencyStyle 没有“$”返回零

    我设置了一个数字格式化程序来将货币字符串转换为十进制值 问题是 如果文本字符串没有前导美元符号 它会转换为 0 而不是有效的匹配数字 所以 3 50 converts to 3 50 3 50 converts to 0 这是转换器的代码
  • 这台机器上似乎运行了太多模拟器实例。正在中止

    当我从 SDK 管理器运行它时 加载过程可以正常工作 但是一旦完成 模拟器就会出现闪烁 然后很快消失 有时加载后什么也没有发生 最糟糕的是 当它加载时 我会收到 太多模拟器实例正在这台机器上运行 正在中止 消息 我想开始制作应用程序 但这似
  • Nuxt Heroku 需要填写什么 baseurl 才能运行?

    这是我的nuxt config js file env baseUrl process env BASE URL http localhost 3000 Axios module configuration https go nuxtjs
  • constexpr 函数内的 if 与 if constexpr

    最近修改了一些if constexpr into if在我的 constexpr 函数中 发现它们仍然可以正常工作并且可以在编译时进行评估 这是一个最小的情况 template