c++ - Enum 不是一个 constexpr?

标签 c++ enums c++14 constexpr static-assert

我有这样一个源代码,有一个枚举,我希望它可以被评估为 constexpr,但编译器给我一个错误,它不是。为什么? EventOrder 是 enum 还是 enum class 并不重要。

#include <limits>
#include <type_traits>

enum class EventOrder
{
        Last = 1'000'000,
        Default = 0,
        Logger = -1024,
        First = -1'000'000
};

template <typename T>
constexpr inline std::underlying_type_t<T> num(T value) {
        static_assert(std::is_enum<T>::value, "num can only be used on enumeration types");
        return static_cast<std::underlying_type_t<T>>(value);
}

constexpr EventOrder sum(const EventOrder order, const std::underlying_type_t<EventOrder> orderDelta)
{
        static_assert(order >= EventOrder::First, "Order Value out of bounds");
        return static_cast<EventOrder>(num(order) + orderDelta);
}

int main( )
{
        constexpr EventOrder e = EventOrder::Default;
        sum(e, 2);
        return 0;
}

它给出了错误:

    $ g++ -std=c++14 EventTest.cc
EventTest.cc: In function ‘constexpr EventOrder sum(EventOrder, std::underlying_type_t<EventOrder>)’:
EventTest.cc:23:2: error: non-constant condition for static assertion
  static_assert(order >= EventOrder::First, "Order Value out of bounds");
  ^
EventTest.cc:23:2: error: ‘order’ is not a constant expression  

为什么 order 不是 constexpr?

编辑 1

那么将参数作为模板变量传递是解决该问题的唯一方法吗?或者你知道一些不同的方法?

#include <limits>
#include <type_traits>

enum class EventOrder
{
        Last = 1'000'000,
        Default = 0,
        Logger = -1024,
        First = -1'000'000
};

template <typename T> constexpr inline std::underlying_type_t<T> num(T value)
{
    static_assert(std::is_enum<T>::value, "num can only be used on enumeration types");
    return static_cast<std::underlying_type_t<T>>(value);
}

template< typename T >
constexpr bool LimitedValue(const T value, const T min, const T max)
{
        return value >= min && value <= max;
}

template <EventOrder orderl, std::underlying_type_t<EventOrder> orderr>
constexpr std::underlying_type_t<EventOrder>  orderSum()
{
        return num(orderl) + orderr;
}

template <EventOrder orderl, std::underlying_type_t<EventOrder> orderr>
constexpr EventOrder order()
{
        static_assert(LimitedValue(orderSum<orderl, orderr>(), num(EventOrder::First), num(EventOrder::Last)), "order out of baunds");
        return static_cast<EventOrder>(orderSum<orderl, orderr>());
}

int main()
{
        EventOrder e = order<EventOrder::Default, 2>();

}

最佳答案

即使该函数是一个 constexpr 函数,它仍然可以使用非 const 参数调用。因此,当编译器处理该函数时,它无法知道 order 的值,也无法在 static_assert 中使用它。

关于c++ - Enum 不是一个 constexpr?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45875323/

相关文章:

c++ - 从limemicro编译lms6suite时出现枚举错误

java - 按字母顺序对 Enum.values() 进行排序,并将它们添加到 Spinner ArrayAdapter

c++ - 将 decltype 与带有尾随返回类型语法的模板化成员函数一起使用时,gcc 中的编译器错误但不是 clang

c++ - 在线程之间解析 OpenCV 帧

c++ - 使用 GDB 调试英特尔 C++ 编译代码

c++ - 对象数组的条目未更新

c++ - 将 OpenSSL 静态库添加到 vc++ 项目

c# - 如何使用枚举值的自定义字符串格式设置枚举绑定(bind)组合框?

c++ - 区别: std::make_unique<char>(size_t size) 和 std::make_unique<char[]>(size_t size)?

c++ - boost::static_visitor 中 operator() 的附加参数