Why should I prefer static constexpr int in a class over enum for class-level integral constants?

后端 未结 3 1303
我寻月下人不归
我寻月下人不归 2021-02-14 08:18

C++17 Update: static constexpr variables are implicitly inline so there\'s no external definition necessary.


Original qu

相关标签:
3条回答
  • 2021-02-14 08:48

    One difference is that you can take the address of a static constexpr but not of an enum.

    Another is that constexpr isn't supported by older versions of the language (it was introduced in C++11).

    I'd use enum only if the values belong together. I'd also give the enum a name that describes that relationship. I wouldn't use an enum for defining unrelated constants.

    0 讨论(0)
  • 2021-02-14 08:49

    The reason I would give you is that using enum { } for constants is a misuse of the term enum. You're not enumerating anything. It's a common misuse, granted; it has its practical advantages; but it's just kind of wrong. There should be a way to say "this is just a compile-time constant and nothing else". constexpr isn't that thing either, but it's closer than enum. And it's rightly the case that you can't enum floating-point values.

    That being said - I often use enums for constants myself, when I want to protect myself against people writing something like void* ptr = &some_constant_value; std::cout << ptr;

    0 讨论(0)
  • 2021-02-14 09:00

    Perhaps no advantage for your usage because you're just using simple fixed integer values.

    But, [AFAIK] constexpr can be more general as it allows initialization from anything that can be evaluated at compile time.

    From type_traits:

     /// integral_constant
      template<typename _Tp, _Tp __v>
        struct integral_constant
        {
          static constexpr _Tp                  value = __v;
          typedef _Tp                           value_type;
          typedef integral_constant<_Tp, __v>   type;
          constexpr operator value_type() const { return value; }
    #if __cplusplus > 201103L
    #define __cpp_lib_integral_constant_callable 201304
          constexpr value_type operator()() const { return value; }
    #endif
        };
    

    Thus, constexpr has usage in metaprogramming.

    The following is a bit rough.

    If you had a function like:

    constexpr unsigned
    bitmask(int bitno)
    {
    
        return 1u << bitno;
    }
    

    You might find a usage such as:

    constexpr unsigned BIT_0 = bitmask(0);
    constexpr unsigned BIT_1 = bitmask(1);
    
    0 讨论(0)
提交回复
热议问题