如何使用在C ++ constexpr函数参数static_assert?

问题描述 投票:11回答:3

我在我的库,进行一些简单的计算几个简短constexpr功能。我在运行时使用这两个和编译时的上下文。

我想在这些函数的体执行一些断言,然而assert(...)不在constexpr功能有效和static_assert(...)不能用于检查函数参数。

例:

constexpr int getClamped(int mValue, int mMin, int mMax) noexcept
{
    assert(mMin <= mMax); // does not compile!
    return mValue < mMin ? mMin : (mValue > mMax ? mMax : mValue);
}

有没有一种方法来检查是否在运行时正在执行或编译时间常数和执行assert只有当它在运行时正在执行的功能?

constexpr int getClamped(int mValue, int mMin, int mMax) noexcept
{
    assert_if_runtime(mMin <= mMax); 
    return mValue < mMin ? mMin : (mValue > mMax ? mMax : mValue);
}
c++ c++11 assert constexpr
3个回答
4
投票

我相信,assert会为你工作,一旦G ++实现N3652, Relaxing constraints on constexpr functions。目前,this status page表明,这还没有得到落实。

assert确实对苹果出货当前铛编译器的工作(在constexpr功能),与-std=c++1y

在这个时候,我什么也看不到在保证一个assert将在constexpr职能的工作标准,并且这样的保证将是一个值得欢迎的除了标准的(至少我)。

更新

理查德·史密斯把我的注意LWG 2234丹尼尔Krügler它试图创建我指的是上面的保证提交。


8
投票

抛出一个异常,因为编译器会忽略运行时部分时,它知道在编译时的异常没有抛出可能是有用的。

#include <cassert>

constexpr int getClamped(int mValue, int mMin, int mMax)
{
    return ( mMin <= mMax ) ? 
           ( mValue < mMin ? mMin : (mValue > mMax ? mMax : mValue) ) :
           throw "mMin must be less than or equal to mMax";
}

int main( int argc, char** argv )
{
    // These two work:
    static_assert( getClamped( 42, 0, 100 ) == 42, "CT" );
    assert( getClamped( argc, 0, 100 ) == argc );

    // Fails at compile-time:
    // static_assert( getClamped( 42, 100, 0 ) == 42, "CT" );

    // Fails at run-time:
    // assert( getClamped( argc, 100, 0 ) == argc );
}

Live example


6
投票

丹尼尔·弗雷的回答细化使用noexceptconstexpr函数打开运行时错误到调用std::terminate。断言失败是不可恢复的;他们应该立即停止的过程。使它们成为例外是一个非常糟糕的主意。

#include <exception>
#include <stdexcept>

struct assert_failure
  : std::logic_error
{
    explicit assert_failure(const char *sz)
      : std::logic_error(sz)
    {}
};

constexpr bool in_range(int i, int j, int k) noexcept
{
    return (i <= j && j <= k) ? true : throw assert_failure("input not in range");
}

int main(int argc, char* argv[])
{
    constexpr bool b1 = in_range(0, 4, 5); // OK!
    constexpr bool b2 = in_range(0, 6, 5); // Compile-time error!
    bool b3 = in_range(0, 4, argc);        // May or may not terminate the process
}

对我来说,运行时错误是这样的:

terminate called after throwing an instance of 'assert_failure'
  what():  input not in range
Aborted (core dumped)

希望帮助。

© www.soinside.com 2019 - 2024. All rights reserved.