User Defined C++11 enum class Default Constructor

后端 未结 3 1279
半阙折子戏
半阙折子戏 2021-02-01 14:22

Is there a way to specify the default constructor of an enum class?

I am using an enum class to specify a set of values which are allowable for

3条回答
  •  灰色年华
    2021-02-01 15:01

    I know that this question is dated and that it already has an accepted answer but here is a technique that might help in a situation like this with some of the newer features of C++

    You can declare this class's variable either non static or static, it can be done in several ways permitted on support of your current compiler.


    Non Static:

    #include 
    #include 
    
    template
    class PinIDs {
    private:
        const std::array ids { IDs... };
    public:
        PinIDs() = default;
        const unsigned& operator[]( unsigned idx ) const {
            if ( idx < 0 || idx > ids.size() - 1 ) {
                return -1;
            }
            return ids[idx];
        }
    };
    

    Static: - There are 3 ways to write this: (First One - C++11 or 14 or higher) last 2 (c++17).

    Don't quote me on the C++11 part; I'm not quite sure when variadic templates or parameter packs were first introduced.

    template
    class PinIDs{
    private:        
        static const std::array ids;
    public:    
        PinIDs() = default;    
        const unsigned& operator[]( unsigned idx ) const {
            if ( idx < 0 || idx > ids.size() - 1 ) {
                return -1;
            }
            return ids[idx];
        }
    };
    
    template
    const std::array PinIDs::ids { IDs... };
    

    template
    class PinIDs{
    private:
        static constexpr std::array ids { IDs... }; 
    public:   
        PinIDs() = default;    
        const unsigned& operator[]( unsigned idx ) const {
            if ( idx < 0 || idx > ids.size() - 1 ) {
                return -1;
            }
            return ids[idx];
        }
    };
    

    template
    class PinIDs{
    private:
        static inline const std::array ids { IDs... };
    public:    
        PinIDs() = default;    
        const unsigned& operator[]( unsigned idx ) const {
            if ( idx < 0 || idx > ids.size() - 1 ) {
                return -1;
            }
            return ids[idx];
        }
    };
    

    All examples above either non-static or static work with the same use case below and provide the correct results:

    int main() {
        PinIDs<4, 17, 19> myId;
    
        std::cout << myId[0] << " ";
        std::cout << myId[1] << " ";
        std::cout << myId[2] << " ";
    
        std::cout << "\nPress any key and enter to quit." << std::endl;
        char c;
        std::cin >> c;
    
        return 0;
    }
    

    Output

    4 17 19
    Press any key and enter to quit.
    

    With this type of class template using a variadic parameter list, you don't have to use any constructor but the default. I did add bounds checking into the array so that the operator[] doesn't exceed bounds of its size; I could of threw an error but with unsigned type I just simply returned -1 as an invalid value.

    With this type, there is no default as you have to instantiate this kind of object via template parameter list with a single or set of values. If one wants to they can specialize this class with a single parameter of 0 for a default type. When you instantiate this type of object; it is final as in it can not be changed from its declaration. This is a const object and still holds to be default constructible.

提交回复
热议问题