2017-02-27 2 views
0

Je veux utiliser C++ 11 enum class comme bitfields et trouver une bonne approche here.Comment utiliser bitmask_operators.hpp avec espace de noms et classes

Mais j'ai collé, si ma déclaration de classe enum n'est pas dans l'espace de noms global mais dans l'espace de noms personnalisé ou à l'intérieur d'une classe à la place. .:

par exemple
#define ENABLE_BIT_OPERATORS(E) template<> struct enable_bitmask_operators<E> { static constexpr bool enable=true; }; 

// anonymous namespace 
namespace { 
enum class Ean { 
    None = 0x00, 
    Bit0 = 0x01, 
    Bit1 = 0x02, 
    Bit2 = 0x04, 
    Bit3 = 0x08, 
}; 
ENABLE_BIT_OPERATORS(Ean) 
} // anonymous namespace 

// custom namespace 
namespace Custom { 
enum class Ecn { 
    None = 0x00, 
    Bit0 = 0x01, 
    Bit1 = 0x02, 
    Bit2 = 0x04, 
    Bit3 = 0x08, 
}; 
ENABLE_BIT_OPERATORS(Ecn) 
} // custom namespace 

// inside class in global namespace 
class MyclassGN { 
public: 
    enum class Ecgn { 
     None = 0x00, 
     Bit0 = 0x01, 
     Bit1 = 0x02, 
     Bit2 = 0x04, 
     Bit3 = 0x08, 
    }; 
    ENABLE_BIT_OPERATORS(Ecgn) 
}; 

// inside class in anonymous namespace 
namespace { 
class MyclassAN { 
public: 
    enum class Ecan { 
     None = 0x00, 
     Bit0 = 0x01, 
     Bit1 = 0x02, 
     Bit2 = 0x04, 
     Bit3 = 0x08, 
    }; 
    ENABLE_BIT_OPERATORS(Ecan) 
}; 
} // anonymous namespace 

// inside class in custom namespace 
namespace Custom { 
class MyclassGN { 
public: 
    enum class Ecgn { 
     None = 0x00, 
     Bit0 = 0x01, 
     Bit1 = 0x02, 
     Bit2 = 0x04, 
     Bit3 = 0x08, 
    }; 
    ENABLE_BIT_OPERATORS(Ecgn) 
}; 
} // custom namespace 

Cela me donne toujours des erreurs:

error: specialization of 'template<class E> struct enable_bitmask_operators' in different namespace 

jusqu'à ce que je place ma spécialisation de modèle pour le même espace que le modèle enable_bitmask_operators dans bitmask_operators.hpp est situé (espace de noms global dans ce cas). Mais je veux que ma spécialisation soit proche de ma déclaration de classe enum.

Dans le article mentionné, ce problème est également commenté par Jay Miller et il semble qu'il fournit une solution. Mais je n'ai pas suivi ses conseils pour résoudre ce problème en bitmask_operators.hpp.

Exemple de code here.

Modifier/partiellement résolu: Je quant à lui, je l'ai travail (juste une question de copier coller de vidage & et les messages d'erreur énigmatiques ;-). Je viens de mettre à jour mon example code en appliquant la solution de fonction de consumm de Jay Millers.

Toutefois, il existe toujours un problème lors de la déclaration de la classe enum dans une classe. La question soulève, quand j'ajoute un cteur à ma classe, comme:

class MyclassGN { 
public: 
    enum class Ecgn { 
     None = 0x00, 
     Bit0 = 0x01, 
     Bit1 = 0x02, 
     Bit2 = 0x04, 
     Bit3 = 0x08, 
    }; 
    ENABLE_BIT_OPERATORS(Ecgn) 
    explicit MyclassGN(Ecgn e_) {} 
}; 

Puis je me suis une erreur:

enclosing class of constexpr non-static member function 'bool MyclassGN::enable_bitmask_operators(MyclassGN::Ecgn)' is not a literal type 

Eh bien, je fixe en ajoutant static mot-clé:

class MyclassGN { 
public: 
    enum class Ecgn { 
     None = 0x00, 
     Bit0 = 0x01, 
     Bit1 = 0x02, 
     Bit2 = 0x04, 
     Bit3 = 0x08, 
    }; 
    static ENABLE_BIT_OPERATORS(Ecgn) 
    explicit MyclassGN(Ecgn e_) {} 
}; 

Mais le problème suivant se pose lorsque j'essaie d'utiliser les opérateurs de masque de bits, par exemple:

class MyclassGN { 
public: 
    enum class Ecgn { 
     None = 0x00, 
     Bit0 = 0x01, 
     Bit1 = 0x02, 
     Bit2 = 0x04, 
     Bit3 = 0x08, 
    }; 
    static ENABLE_BIT_OPERATORS(Ecgn) 
    explicit MyclassGN(Ecgn e_): e(e_) { 
     e |= Ecgn::Bit3; 
    } 
private: 
    Ecgn e; 
}; 

J'ai eu une erreur:

no match for 'operator|=' (operand types are 'MyclassGN::Ecgn' and 'MyclassGN::Ecgn') 

exemple mise à jour qui montre l'erreur se trouve here.

+0

* "Mais je n'ai pas suivi ses conseils" * Pouvez-vous nous montrer votre tentative, s'il vous plaît? – dyp

Répondre

1

Exemple de code, basé sur bitmask_operators.hpp de Anthony Williams et également appliqué suggestion Jay Millers (fonction constexpr au lieu du modèle <> struct) pour résoudre le problème d'espace de noms est situé here.

Notez que lors de la déclaration de la classe enum à l'intérieur d'une classe, la fonction constexpr doit être précédée du mot clé friend (en tant que dyp suggéré dans le commentaire ci-dessous). Exemple:

class Myclass { 
public: 
    enum class E { 
     None = 0x00, 
     Bit0 = 0x01, 
     Bit1 = 0x02, 
     Bit2 = 0x04, 
     Bit3 = 0x08, 
    }; 
    friend ENABLE_BIT_OPERATORS(E) 
}; 
+1

Vous pouvez utiliser une fonction friend à l'intérieur de la classe (exemple: http: //coliru.stacked-crooked.com/a/eecfd85c6e1089e0), je ne sais pas comment le faire avec une seule macro, sauf pour déclarer cette fonction à namespace-scope et utiliser des identifiants qualifiés pour faire référence à l'énumération. Mais je déteste les macros de toute façon, donc avoir à la fois 'constexpr bool enable_bitmask_operators' et' friend constexpr enable_bitmask_operators' serait bien par moi. – dyp

+0

Oui, en utilisant le mot-clé 'friend', faites le travail. – Joe