Static constexpr int vs old-fashioned enum: when and why?

前端 未结 3 1548
甜味超标
甜味超标 2020-12-15 03:53

This is maybe a basic question, but I cannot see the response by myself right now.

Consider the following code:

template
struct T {
            


        
相关标签:
3条回答
  • 2020-12-15 04:31

    The currently accepted answer by SergeyA no longer holds as of C++17 (Definitions and ODR).

    Every declaration is a definition, except for the following:

    • ...
    • (deprecated) Namespace scope declaration of a static data member that was defined within the class with the constexpr specifier
    struct S {
        static constexpr int x = 42; // implicitly inline, defines S::x
    };
    constexpr int S::x; // declares S::x, not a redefinition
    

    Hence, as of C++17, I would use the static constexpr definition which is more expressive than the enum.

    0 讨论(0)
  • 2020-12-15 04:34

    I suspect it's legacy code.

    enum { value = (b ? 42 : 0) };
    

    is valid code in C++03 as well as C++11.

    static constexpr int value = (b ? 42 : 0);
    

    is valid only in C++11.

    Even more, is there any case for which one of them is not a viable solution?

    Both are viable solutions in C++11. The choice of which one to use depends on a team. It's going to be a matter of a policy decision.

    As the answer by SergeyA indicates, enum are true constants. You cannot ODR-use them. You can ODR-use a constexpr. Depending on which of these is desirable for your application, you can decide whether to use enums or constexprs.

    0 讨论(0)
  • 2020-12-15 04:43

    There will be no noticeable difference for integral constants when used like this.

    However, enum is actually better, because it is a true named constant. constexpr integral constant is an object which can be, for example, ODR-used - and that would result in linking errors.

    #include <iostream>
    
    struct T {
        static constexpr int i = 42;
        enum : int {x = 42};
    };
    
    void check(const int& z) {
        std::cout << "Check: " << z << "\n";
    }
    
    int main() {
        // check(T::i); // Uncommenting this will lead to link error
        check(T::x);
    }
    

    When check(T::i) is uncommented, the program can not be linked:

    /tmp/ccZoETx7.o: In function `main': ccc.cpp:(.text+0x45): undefined reference to `T::i' collect2: error: ld returned 1 exit status

    However, the true enum always works.

    0 讨论(0)
提交回复
热议问题