问题
I have some class that I would like to be initialized at compile time by an initializer list that needs some level of validation.
I first tried static_assert but that wouldn't compile with the error "non-constant condition for static assertion"
What is the best way to causing a build error with this?
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
回答1:
Use a construct that cannot be used at compile time, e.g., an exception:
constexpr foo(std::initializer_list<bar> items)
{
for (auto&& i : items) {
if (i == 12) {
throw std::invalid_argument{""}; // for example
}
}
}
or a false assertion if exception is disabled:
constexpr foo(std::initializer_list<bar> items)
{
for (auto&& i : items) {
assert(i != 12);
}
}
or call a runtime function if NDEBUG
is defined:
constexpr foo(std::initializer_list<bar> items)
{
for (auto&& i : items) {
if (i == 12) {
std::cerr << "Error\n";
}
}
}
A diagnostic is required if runtime-only expressions are evaluated as a part of the evaluation of a constant expression.
static_assert
does not work because the argument thereto is required to be a constant expression, which arguments to constexpr
functions are not.
来源:https://stackoverflow.com/questions/60336545/validation-of-an-stdinitializer-list-in-constexpr-context