有条件地static_assert函数是否称为constexpr
Conditionally static_assert if function is called constexpr
我知道有一个关于constexpr((运算符的建议,但这还没有在gcc/clang中实现。我也知道使用一些技巧,如机器代码编辑:
http://saadahmad.ca/detecting-evaluation-context-inside-constexpr-functions/
我想知道是否有一个有点有限的解决方案:
struct F {
constexpr F(int v) {
if constexpr(constexpr()) {
static_assert(v > 0);
}
else {
assert(v > 0);
}
}
};
// ...
constexpr F f{0}; // should trigger a compile-time error
我知道static_assert不能以这种方式使用,但这只是为了澄清问题。
在你的特定情况下,你可以只保留断言 - 当条件错误时,它将阻止编译,因为断言处理程序是非 constexpr:
#include <cassert>
struct F {
constexpr F(int v) {
assert(v >0);
}
};
// ...
constexpr F f1{0}; // doesn't compile in debug
constexpr F f2{1}; // compiles
但是,这不会在发布中触发编译时错误。这可以通过做出自己的断言并添加对一些非 constepxr 函数的调用来解决:
#include <cassert>
// some non-constexpr function
void AssertConditionFailed()
{
}
#define ASSERT_WIH_COMPILE_TIME_CHECK(...)
assert(__VA_ARGS__);
if (!(__VA_ARGS__))
{
AssertConditionFailed();
}
struct F {
constexpr F(int v) {
ASSERT_WIH_COMPILE_TIME_CHECK(v >0);
}
};
// ...
constexpr F f1{0}; // doesn't compile
constexpr F f2{1}; // compiles
不是以如此直接的方式,因为根本不允许static_assert
,同样尝试使用 v
作为模板参数也会失败,因此不使用enable_if
类型解决方案。
出于错误的目的,如果 constexpr 导致异常,您将收到编译错误。
您可以使用宏,例如 assert
(自 C++14 起允许(,允许在发布版本中对其进行优化并保留原始调试运行时行为。
constexpr int foo(int v)
{
if (v < 0) throw std::invalid_argument("invalid v");
return v * 2;
}
int main() {
int a = -1;
int a2 = foo(a); // Not evaluated at compile time
constexpr int b = foo(2);
constexpr int c = foo(-1); // ERROR
}
相关文章:
- 是否可以使用if constexpr删除控制流语句
- 更多constexpr容器是否需要mark_immutable_if_consexpr
- 添加静态constexpr成员是否会更改结构/类的内存映射
- 是否可以将带有字符串化运算符的宏转换为 constexpr?
- 将INT32BE宏转换为 constexpr 是否正确?
- 静态 constexpr 类成员变量对多线程读取是否安全?
- 任意大小的 constexpr 数组是否可以用作 switch 语句中的案例?
- 在 constexpr 构造函数中初始化数组是否合法?
- G++ 编译器是否在未使用返回值的情况下将 constexpr 函数视为常规函数?
- 是否使用静态 constexpr 变量 odr?
- 是否可以跨多个源文件构建 constexpr 数据结构?
- 如何判断是否在编译时计算了"constexpr"(无需手动检查)
- 是否可以将变体的索引作为 constexpr 变量获取?
- 非 constexpr 变量模板的开销是否为零?
- 是否已经有一个 constexpr std::bit_cast 与 g++ 一起使用
- 是否可以使用"if constexpr"来声明具有不同类型和init-expr的变量
- 在类外部初始化的 constexpr 静态成员的声明中是否需要 constexpr 说明符
- 是否可以以编程方式初始化 constexpr std::array 成员
- 是否都是隐式内联的 constexpr 变量
- 是否有一种非间接、非黑客的方式来保证 constexpr 函数仅在编译时可调用?