Question

C ++ est principalement un sur-ensemble de C, mais pas toujours. En particulier, alors que les valeurs d’énumération converties implicitement en C et C ++ sont converties en int, l’inverse n’est pas vrai: c’est seulement en C que les ints sont reconvertis en valeurs d’énumération. Ainsi, les drapeaux définis par les déclarations d’énumération ne fonctionnent pas correctement. Par conséquent, c’est OK en C mais pas en C ++:

typedef enum Foo
{
    Foo_First = 1<<0,
    Foo_Second = 1<<1,
} Foo;

int main(void)
{
    Foo x = Foo_First | Foo_Second; // error in C++
    return 0;
}

Comment ce problème devrait-il être traité efficacement et correctement, idéalement sans nuire à la nature conviviale du débogueur consistant à utiliser Foo comme type de variable (il se décompose en composant, le bitflags dans les montres, etc.)?

Considérez également qu’il peut y avoir des centaines d’énumérations de drapeaux de ce type et plusieurs milliers de points d’utilisation. Idéalement, une surcharge efficace de la part d’un opérateur suffirait, mais elle devrait être efficace; l'application à laquelle je pense est liée au calcul et a la réputation d'être rapide.

Clarification: je traduis un grand programme C (& 30000) C en C ++, je recherche donc une traduction efficace, à la fois au moment de l’exécution et au moment du développement. Il suffit parfois de plusieurs semaines pour insérer des modèles dans tous les emplacements appropriés.

Était-ce utile?

La solution

Pourquoi ne pas simplement renvoyer le résultat à un Foo?

Foo x = Foo(Foo_First | Foo_Second);

EDIT: Je n’ai pas compris l’ampleur de votre problème lorsque j’ai répondu à cette question pour la première fois. Ce qui précède fonctionnera pour faire quelques corrections ponctuelles. Pour ce que vous voulez faire, vous devrez définir un | opérateur qui prend 2 arguments Foo et retourne un Foo:

Foo operator|(Foo a, Foo b)
{
    return Foo(int(a) | int(b));
}

Les internautes sont là pour empêcher une récursion indésirable.

Autres conseils

Cela ressemble à une application idéale pour un casting - vous devez dire au compilateur que vous voulez effectivement instancier un Foo avec un entier aléatoire.

Bien sûr, techniquement parlant, Foo_First | Foo_Second n'est pas une valeur valide pour un Foo.

Laissez le résultat sous la forme d'un entier ou statique:

Foo x = static_cast<Foo>(Foo_First | Foo_Second); // not an error in C++
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top