在 constexpr 上下文中验证 std::initializer_list
Validation of an std::initializer_list in constexpr context
我有一些 class 我想在编译时通过需要一定程度验证的初始化程序列表进行初始化。
我首先尝试了 static_assert,但无法编译并出现错误 "non-constant condition for static assertion"
导致构建错误的最佳方法是什么?
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 << "Error\n";
}
}
}
如果将仅运行时表达式作为常量表达式求值的一部分进行求值,则需要进行诊断。
static_assert
不起作用,因为它的参数必须是常量表达式,而 constexpr
函数的参数不是。
我有一些 class 我想在编译时通过需要一定程度验证的初始化程序列表进行初始化。
我首先尝试了 static_assert,但无法编译并出现错误 "non-constant condition for static assertion"
导致构建错误的最佳方法是什么?
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 << "Error\n";
}
}
}
如果将仅运行时表达式作为常量表达式求值的一部分进行求值,则需要进行诊断。
static_assert
不起作用,因为它的参数必须是常量表达式,而 constexpr
函数的参数不是。