constexpr上下文中std::initializer_list的验证

Validation of an std::initializer_list in constexpr context

本文关键字:list 验证 initializer std constexpr 上下文      更新时间:2023-10-16

我有一些类,希望在编译时由需要某种级别验证的初始值设定项列表初始化。

我第一次尝试static_assert,但编译时不会出现错误"静态断言的非恒定条件">

导致生成错误的最佳方法是什么?

class foo {
public:
constexpr foo(std::initializer_list<bar> items) {
for(auto &&i: items) {
if(i == 12) // example validation logic
// fail the build
}
}
}
constexpr foo foo_list({0,1,2,3,4,5});// should succeed
constexpr foo foo_list_bad({0,1,12,4,68});// should fail to build

使用编译时不能使用的构造,例如异常:

constexpr foo(std::initializer_list<bar> items)
{
for (auto&& i : items) {
if (i == 12) {
throw std::invalid_argument{""}; // for example
}
}
}

如果异常被禁用,则为错误断言:

constexpr foo(std::initializer_list<bar> items)
{
for (auto&& i : items) {
assert(i != 12);
}
}

或者如果定义了NDEBUG,则调用运行时函数:

constexpr foo(std::initializer_list<bar> items)
{
for (auto&& i : items) {
if (i == 12) {
std::cerr << "Errorn";
}
}
}

如果仅运行时表达式作为常量表达式求值的一部分进行求值,则需要进行诊断。

static_assert不起作用,因为它的自变量必须是常量表达式,而constexpr函数的自变量则不是。