在std :: is_constant_evaluated时如何获取常量表达式?

问题描述

让我们从示例(godbolt)开始:

constexpr int len(int v) {
    if (std::is_constant_evaluated()) {
        // static_assert(v > 0); // ERR: 'v' is not a constant expression
        return v;
    } else {
        return 0;
    }
}

using A = std::array<int,len(3)>;

问题是static_assert无法编译(gcc / clang最新的10.x版本)。显然,当v返回constexpr时,std::is_constant_evaluated并没有被理解为true。但是很明显,通过使用len,实际上是这样。

问题:是否可以且仅当constexpr时才将变量用作std::is_constant_evaluated?如果可以,怎么办?

解决方法

显然,当v返回constexpr时,std::is_constant_evaluated并没有意识到是true。但是很明显,通过使用len,实际上是这样。

不,实际上不是。

函数参数不是常量表达式。无论您是否处于持续评估之中,都没有关系。您不能在任何上下文中将v用作常量表达式。 static_assert需要一个常量表达式-这就是为什么您不能使用v的原因。

问题:当且仅当std::is_constant_evaluated时,才可以将变量用作constexpr吗?如果可以,怎么办?

不,不是。因为为了将变量用作常量表达式,所以这是一个模板。 is_constant_evaluated不能有条件地将您的函数转换为函数模板,而这并不是编译过程的工作方式。参见P0992

,

不可能,但也不必要。

您可以static_assert来代替throw。由于您处于constexpr上下文中,因此会出现编译时错误。

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...