Comparing enum from a template class - is it safe?

So, a simple question is really illustrated by the example below. When you compile this, the compiler appropriately (?) Reports a warning (which we compare barfoo<int>::bar with barfoo<foo>::bar ), now this bar is an enumeration - can I safely ignore this warning?

 #include <iostream> using namespace std; struct foo { }; template <typename bob = int> struct barfoo { enum bar { ONE, TWO, THREE }; bar action() const { return TWO; } }; template <barfoo<>::bar eAction = barfoo<>::ONE> struct IsAction { template <typename bf> static bool check(bf const& cState) { return cState.action() == eAction; } }; int main(void) { barfoo<foo> c; cout << IsAction<>::check(c) << endl; return 0; } 

Given that I am committed to removing warning messages, is there a way to satisfy the compiler without moving the enum out?

+4
source share
3 answers

The numeric representation of the enumerations will be the same, so it is safe to compare them directly (or even throw between them, although you may need to go through an int to satisfy the compiler). If you want to disable the warning, one approach would be to drop both of them to ints before doing the comparison: (int)cState.action == (int)eAction . You might be able to add a templated operator== for an enumeration to do this automatically, but not sure about that.

Alternatively, depending on how you define "without moving the enum out", you can get from a non-templated base class that serves to store the enumeration definition, as in http://codepad.org/8bVlcas3

+3
source

I would move it outside, but to the base class:

 struct barenum { enum bar { ONE, TWO, THREE }; protected: // because we are going to derive from it without a virtual destructor ~barenum() {} }; template <typename bob = int> struct barfoo : barenum { bar action() const { return TWO; } }; 
+1
source

moves enum to parent barfoo count?

 #include <iostream> using namespace std; struct foo { }; struct barfoobase { enum bar { ONE, TWO, THREE }; }; template <typename bob = int> struct barfoo : public barfoobase { bar action() const { return TWO; } }; template <barfoobase::bar eAction = barfoobase::ONE> struct IsAction { template <typename bf> static bool check(bf const& cState) { return cState.action() == eAction; } }; int main(void) { barfoo<foo> c; cout << IsAction<>::check(c) << endl; return 0; } 

edit: Oh, this answer has already been posted ...

0
source

Source: https://habr.com/ru/post/1336454/


All Articles