Validation of an std::initializer_list in constexpr context

一笑奈何 提交于 2021-01-28 09:40:05

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!