3

I have some global constexpr Masks that I would like to make a part of my Mask class as a static constexpr to reduce globals in main.cpp

Currently this works:

  • main.cpp has:

    constexpr Mask cg_completeMask(0xffffffffffffffffull, 0x1ffff);
    
  • Mask.hpp has (reduced for SO):

    class Mask {
        unsigned long long m_64;
        unsigned int       m_32;
    
    public:        
        constexpr Mask(const unsigned long long ac_64, const unsigned int ac_32) :
            m_64(ac_64),
            m_32(ac_32)
        {}
    };
    

What I tried to move the global Masks from main.cpp:

  • Mask.hpp has:

    class Mask {
        unsigned long long m_64;
        unsigned int       m_32;
    
    public:        
        static constexpr Mask completeMask;
    
        constexpr Mask(const unsigned long long ac_64, const unsigned int ac_32) :
            m_64(ac_64),
            m_32(ac_32)
        {}
    };
    
  • Mask.cpp has:

    constexpr Mask Mask::completeMask(0xffffffffffffffffull, 0x1ffff);
    

What I tried produces these errors:

In file included from main.cpp:3:0:
Mask.hpp:12:27: error: constexpr static data member 'completeMask' must have an initializer
     static constexpr Mask completeMask;
                           ^
In file included from Mask.cpp:1:0:
Mask.hpp:12:27: error: constexpr static data member 'completeMask' must have an initializer
     static constexpr Mask completeMask;
                           ^
sergej
  • 17,147
  • 6
  • 52
  • 89
asimes
  • 5,749
  • 5
  • 39
  • 76
  • 1
    May be duplicate of this http://stackoverflow.com/questions/33177955/static-constexpr-of-class-inside-class-link-problems ? – fghj Nov 05 '15 at 07:13
  • 1
    @user1034749, Not quite, I have a `static constexpr` member that is not a function member – asimes Nov 05 '15 at 07:20
  • Follow this question you can find out that you can not declare constexpr of type `Mask` inside `class Mask` that is your first problem. – fghj Nov 05 '15 at 07:22
  • You have 1) an incomplete type inside your type, 2) an infinite recursion of type content: each `Mask` contains a `Mask`. Try to write down the contents of a `Mask` object on paper. Stop when you reach the end of the page, to save trees. It never ends! – rubenvb Nov 05 '15 at 09:50

1 Answers1

1

Best I could get was this, which ought to do what you want - but does unfortunately expose your constants in the interface. This is unavoidable I'm afraid.

* Mask.hpp

class Mask {
    unsigned long long m_64;
    unsigned int       m_32;


    // private constructor
    constexpr Mask(const unsigned long long ac_64, const unsigned int ac_32) :
    m_64(ac_64),
    m_32(ac_32)
    {}

public:

    // public declarations
    inline static constexpr Mask complete();
    inline static constexpr Mask partial();

};

// inline definitions
constexpr Mask Mask::complete()
{
    return Mask(0xffffffffffffffffull, 0x1ffff);
}

constexpr Mask Mask::partial()
{
    return Mask(0xf0f0f0f0f0f0f0f0ull, 0x1ffff);
}

example of use:

auto main() -> int
{
    auto m1 = Mask::complete();
    auto m2 = Mask::partial();

    return 0;
}
Richard Hodges
  • 68,278
  • 7
  • 90
  • 142