繁体   English   中英

如果函数名为constexpr,则条件为static_assert

[英]Conditionally static_assert if function is called constexpr

我知道有一个constexpr()运算符的提议,但这还没有在gcc / clang中实现。 我也知道有一些使用机器代码编辑等技巧:

http://saadahmad.ca/detecting-evaluation-context-inside-constexpr-functions/

我想知道是否有一个有点限制的解决方案:

struct F {
    constexpr F(int v) {
         if constexpr(constexpr()) {
             static_assert(v > 0);
         }
         else {
             assert(v > 0);
         }
    }
};

// ...

constexpr F f{0}; // should trigger a compile-time error

我知道static_assert不能以这种方式使用,但这只是为了澄清问题。

在您的特定情况下,您可以保留断言 - 当条件错误时它将阻止编译,因为断言处理程序是非constexpr:

#include <cassert>

struct F {
    constexpr F(int v) {
         assert(v >0);
    }
};

// ...

constexpr F f1{0}; // doesn't compile in debug
constexpr F f2{1}; // compiles

但是,这不会在发布时触发编译时错误。 它可以通过自己的断言和添加对某些非constepxr函数的调用来解决:

#include <cassert>

// some non-constexpr function
void AssertConditionFailed()
{
}

#define ASSERT_WIH_COMPILE_TIME_CHECK(...) \
    assert(__VA_ARGS__); \
    if (!(__VA_ARGS__)) \
    { \
        AssertConditionFailed(); \
    }\

struct F {
    constexpr F(int v) {
         ASSERT_WIH_COMPILE_TIME_CHECK(v >0);
    }
};

// ...

constexpr F f1{0}; // doesn't compile
constexpr F f2{1}; // compiles

不是以这种直接的方式,因为static_assert将不会被允许在那里,并且类似地尝试使用v作为模板参数将失败,因此不使用enable_if类型解决方案。

出于错误的目的,如果constexpr导致异常,则会出现编译错误。

您可以使用诸如assert的宏(从C ++ 14开始允许),允许它在发布版本中进行优化并保持原始的调试运行时行为。

constexpr int foo(int v)
{
    if (v < 0) throw std::invalid_argument("invalid v");
    return v * 2;
}

int main() {
    int a = -1;
    int a2 = foo(a); // Not evaluated at compile time
    constexpr int b = foo(2);
    constexpr int c = foo(-1); // ERROR
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM