1

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

2
  • Throw an exception? It won't be done at compile time. Commented Feb 21, 2020 at 10:23
  • Argument are not constexpr, Could you pass std::index_sequence instead of initializer_list? Commented Feb 21, 2020 at 10:24

1 Answer 1

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.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for that, Are there ways other that exceptions? Some of the code I'd like to write this for have exceptions disabled, and it would be nice if there was a second way.
@Mitchk I added some alternatives.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.