如何在 constexpr 函数中执行运行时断言? [英] How can I do a runtime assert in a constexpr function?

查看:43
本文介绍了如何在 constexpr 函数中执行运行时断言?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

据我所知,constexpr 函数可以在编译时和运行时执行,这取决于整个评估是否可以在编译时完成.

From what I understand, a constexpr function can be executed at compile time as well as runtime, depending on if the entire evaluation can be done at compile time or not.

但是,您不能重载此函数以获得运行时和编译时对应物.

However, you cannot overload this function to have a runtime and a compile time counterpart.

所以我的问题是,如何放入运行时断言以确保运行时函数的执行与我的 static_assert 一起传递有效参数?

So my question is, how can I put in a runtime assert to ensure that the execution of the runtime function is passed valid parameters along with my static_assert?

推荐答案

Eric Niebler 在 C++11 中的 Assert 和 Constexpr,他指出在 C++11 中不允许在 constexpr 函数中使用断言,但在 C++14 中是允许的(作为放宽限制的一部分constexpr 函数建议)并提供以下代码片段:

Eric Niebler covers this issue well in Assert and Constexpr in C++11, he points out that using assert in a constexpr function is not allowed in C++11 but it is allowed in C++14(As part of the Relaxing constraints on constexpr functions proposal) and provides the following snippet:

constexpr bool in_range(int val, int min, int max)
{
    assert(min <= max); // OOPS, not constexpr
    return min <= val && val <= max;
}

如果我们必须支持 C++11,那么还有一些替代方案.显而易见的是使用 throw ,但正如他指出的那样,这会将本应是不可恢复的错误变成可恢复的错误,因为您可以捕获异常.

If we have to support C++11 then there are some alternatives. The obvious one is the using throw but this as he points out this turns what should be a unrecoverable error into a recoverable one since you can catch the exception.

他提出了一些替代方案:

He suggest some alternatives:

  1. 将 throw 与 noexcept 说明符一起使用:

constexpr bool in_range(int val, int min, int max) noexcept 
{
  return (min <= max)
    ? min <= val && val <= max
    : throw std::logic_error("Assertion failed!");
}

如果有异常离开,函数 std::terminate 将被调用.

if an exception leaves the function std::terminate will be called.

从构造函数调用 std::quick_exit异常类型:

Call std::quick_exit from the constructor of an exception type:

struct assert_failure
{
    explicit assert_failure(const char *sz)
    {
        std::fprintf(stderr, "Assertion failure: %s
", sz);
        std::quick_exit(EXIT_FAILURE);
    }
};

constexpr bool in_range(int val, int min, int max)
{
    return (min <= max)
      ? min <= val && val <= max
      : throw assert_failure("min > max!");
}

  • 向异常类型的构造函数传递断言的 lambda 表达式:

  • Pass a lambda expression that asserts to the constructor of an exception type:

    constexpr bool in_range(int val, int min, int max)
    {
        return (min <= max)
          ? min <= val && val <= max
          : throw assert_failure(
              []{assert(!"input not in range");}
            );
    }
    

  • 这篇关于如何在 constexpr 函数中执行运行时断言?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆