c++ - 在constexpr上下文中验证std::initializer_list

标签 c++ c++17 constexpr initializer-list

我有一些我想在编译时由需要某种程度验证的初始化列表初始化的类。

我首先尝试使用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 << "Error\n";
        }
    }
}

如果仅运行时表达式作为常量表达式求值的一部分进行求值,则需要进行诊断。
static_assert不起作用,因为要求其参数为常量表达式,而constexpr函数的参数则为常数表达式。

关于c++ - 在constexpr上下文中验证std::initializer_list,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60336545/

相关文章:

c++ - 使用 noexcept 的函数指针的重载解析

c++ - 如何将模板 lambda 传递给函数并将其与不同类型一起使用

c++ - 是否可以定义一个宏来定义枚举类和返回枚举元素计数的 GetCount() 方法?

c++ - 扩展编译器以在编译时评估 "complicated"函数(具有已知输入值),超出 `constexpr` 范围

c++ - 我的小程序中有某种断言错误

c++ - 在局部变量上使用 const

c++ - 一个简单类模板的c++17中的 friend 流运算符

c++ - constexpr 函数和硬编码参数

c++ - 具有成员变量的 Const 对象数组 = 先前索引成员变量的总和

c++ - 抑制从 const 方法打印的消息