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

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

问题描述

从我的理解,constexpr函数可以在编译时以及运行时执行,这取决于整个评估是否可以在编译时完成。



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

解决方案

Eric Niebler在 Assert and Constexpr in C ++ 11 ,他指出,在C ++ 11中不允许在constexpr函数中使用assert,但在C ++ 14中允许使用assert( 作为constexpr函数放松约束的一部分),并提供以下代码段:

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

如果我们必须支持C ++ 11,明显的一个是使用抛出,但这是因为他指出这会将一个不可恢复的错误变成一个可恢复的错误,因为你可以捕获异常。



他建议一些


  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将被调用。 p>


  2. 致电 std: :quick_exit 来自异常类型的构造函数:

      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!);
    }


  3. 传递声明到异常类型的构造函数的lambda表达式:

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



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.

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 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;
}

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. Using throw with the noexcept specifier:

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

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

  2. 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\n", 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!");
    }
    

  3. 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天全站免登陆