0

I can't figure out how to implement a bitmask parameter for my class.

Specifically my CreateMenuDlg function

I've searched google quite a bit, finding all sorts of forum questions that ask about bitmasks, bitfields, etc. and everyone posts minimal example code
I keep finding people using #define but that wouldn't work for my class since I need to call it from main dialog with something like this:

DialogMenu *p_dlgMenu = new DialogMenu( this, &p_dlgMenu, this );
p_dlgMenu->CreateMenuDlg( ( DialogMenu::CLOSES | DialogMenu::WINDOW_HANDLER ), DialogMenu::DLG_CHECKOUT );

Here's my code:

class DialogMenu : public CDialog
{
    DECLARE_DYNAMIC(DialogMenu)

public:
    enum dlgFlags
    {
        HIDES = 2^0,
        CLOSES = (2^0)+1,
        WINDOW_HANDLER = 2^1,
        MSG_HANDLER = (2^1)+1,
        DLG_SHOPPING_MENU = 2^2,
        DLG_DYNAMIC_MENU = (2^2)+1,
    };

    dlgFlags operator|=( dlgFlags first, flgFlags second)
    {
        return (dlgFlags)( (unsigned)first | (unsigned)second );
    }

    enum dlgType { DLG_CHECKOUT, DLG_INVENTORY_EDIT, DLG_SHIPPING_RECEIVING };

    DialogMenu( CDialog * const, DialogMenu ** const, CWnd* pParent = NULL );
    void PostNcDestroy();
    virtual ~DialogMenu();

    void CreateMenuDlg( dlgFlags paramFlags = ( CLOSES | MSG_HANDLER | DLG_DYNAMIC_MENU ), dlgType paramType = DLG_CHECKOUT );

protected:
    virtual void DoDataExchange(CDataExchange * pDX);

    CDialog * m_parent;
    DialogMenu ** m_self;  
};


For which I'm receiving errors from my bitmask enumeration not being int.

dialogmenu.h(21): error C2440: 'default argument' : cannot convert from 'int' to 'DialogMenu::dlgFlags'
Conversion to enumeration type requires an explicit cast (static_cast, C-style cast or function-style cast)


But my OR operator overload should be taking care of that cast!

If I have to I'll abandon bitflags altogether, but I'm trying to get the hang of them and I get more points on my project per C++ subject covered and bitfields was the most recent thing we learned. (Although we never learned how to implement them as enumerations, only playing with them on character variables.)

Numerials
  • 3
  • 2
  • Doesn't applying the recommended cast from the error message fix your problem? – πάντα ῥεῖ Nov 27 '14 at 09:09
  • How do I do that? Cast it directly in the default parameter? I need users of this class (my group-mates) to be able to use the function with just DialogMenu::CLOSES and not have to cast it each time they call the function. – Numerials Nov 27 '14 at 09:14
  • By the way, you know that ^ means xor, right? – harold Nov 27 '14 at 16:10
  • Awh thats what was wrong with it. I didn't know that I just knew it wasn't coming out correctly so I had to go change it to Hides = 0, Closes = 1, Window_Handler = 0, Msg_Handler = 2, Dlg_Shop = 0, Dlg_Dynamic = 4 – Numerials Nov 27 '14 at 18:23

2 Answers2

1

This is not an OR operator for enum dlgFlags, instead it's an operator|= for DialogMenu (having 3 operands including *this, so it doesn't compile):

dlgFlags operator|=( dlgFlags first, flgFlags second)
{
    return (dlgFlags)( (unsigned)first | (unsigned)second );
}

Change it to

friend dlgFlags operator|(dlgFlags first, dlgFlags second)
{
    return (dlgFlags)( (unsigned)first | (unsigned)second );
}

friend keyword is needed to make it not a member of DialogMenu. Personally I'd prefer to move it out of the DialogMenu class together with enum dlgFlags itself:

enum dlgFlags
{
    HIDES = 2^0,
    // ...
};

dlgFlags operator|(dlgFlags first, dlgFlags second)
{
    return (dlgFlags)( (unsigned)first | (unsigned)second );
}

class DialogMenu : public CDialog
{
     // ...
}
Anton Savin
  • 40,838
  • 8
  • 54
  • 90
  • This one worked!
    Just had to add DialogMenu:: scope for the casting after return.

    Only reason I want it to stay inside class is because I'm trying to emulate fstream's ios::open, which is the instruction given by our instructor, so I need scope resolution to use class DialogMenu.
    Thanks!
    – Numerials Nov 27 '14 at 09:24
0

Use an explicit cast for each value within the enum declaration itself.

Resource
  • 524
  • 4
  • 16