C++ enum variable setting to more than one value [duplicate] - c++

I have a problem putting method args to my class:
class A {
public:
enum Mode {ModeA, ModeB, ModeC};
... // other methods, constructor etc
void setMode(Mode m) {
mMode = m;
}
private:
Mode mMode;
}
int main(int argc, char **argv) {
A a;
a.setMode(A::ModeA | A::ModeC );
return 0;
}
The problem, I get a C++ compiler error invalid vconversion from int to A::Mode,
I dont understand, why I can't concat to enum values? I need to concat values in my
code, so any help to solve this would be very nice.

The result of operator| for two enums is not an enum by default. After your class, add something like this:
A::Mode operator|( A::Mode a, A::Mode b )
{
return A::Mode( int( a ) | int( b ) );
}
if your standard library supports it, the following is more future proof as the conversion to int is not always correct:
A::Mode operator|( A::Mode a, A::Mode b )
{
typedef std::underlying_type< A::Mode >::type UL;
return A::Mode( static_cast< UL >( a ) | static_cast< UL >( b ) );
}
Unlike the other answer, you just add this once (to the right place) and all uses are automatically covered.

May be you need this :
a.setMode( (A::Mode) (A::ModeA | A::ModeC ));
A::ModeA | A::ModeC makes an int so cast it to A::Mode again

Underlying type of your enum is in this case probably int and your compiler can not rely on the flag constructed using the | (bitwise or) being a valid value from this enum.
However, you know that the result will be a valid value from this enum, so you could do:
A::Mode newMode = (A::Mode) (A::ModeA | A::ModeC);
a.setMode(newMode);

Related

Define enum element value using an operation on another enum values

Here is what I need to do: define, inside a class, two enumerations, the second having elements defined using elements values from the first.
So something like this:
class MyClass
{
public:
enum class Elem {
A=1, B=2, C=4, D=8
};
enum class Group {
first = Elem::A | Elem::B,
second = Elem::A | Elem::C,
//...
}; <-- compilation error
};
However, this does not compile due to the fact that | is not defined by default for enum classes.
I tried to define the | operator for Elem enum, outside of the MyClass class (after the class body), but the operator is then not known at the time the Group enum is defined.
So I then tried the following, i.e. defining a constexpr function inside the class:
class MyClass
{
public:
enum class Elem {
A=1, B=2, C=4, D=8
};
constexpr static unsigned int merge(
std::initializer_list<MyClass::Elem> list)
{
//Test only: should be an '|' on all list elements
return 1;
}
enum class Group {
first = merge({Elem::A,Elem::B}),
second = merge({Elem::A,Elem::C}),
/*...*/
};
};
But I get the following error:
error: static constexpr unsigned int
merge(std::initializer_list list) called in a constant
expression
I understood from here and there that the merge method is considered declared and usable only after the class has been fully declared.
The last solution I can think of is using macros like this:
#define MERGE2ELEMS( a, b ) static_cast<unsigned int>(a) | static_cast<unsigned int>(b)
#define MERGE3ELEMS( a, b, c ) static_cast<unsigned int>(a) | MERGE2ELEMS( b, c )
#define MERGE4ELEMS( a, b, c, d ) static_cast<unsigned int>(a) | MERGE3ELEMS( b, c, d )
#define MERGE5ELEMS( a, b, c, d, e ) static_cast<unsigned int>(a) | MERGE4ELEMS( b, c, d, e )
...
But I need to be able to merge up to 20 Elems and writing 20 macros like this does not seem to be a suitable solution.
What would be the way to go here?
You may play with the order of definition:
class MyClass {
public:
enum class Elem { A = 1, B = 2, C = 4, D = 8 };
enum class Group;
};
constexpr MyClass::Elem operator|(
const MyClass::Elem& l, const MyClass::Elem& r) {
return static_cast<MyClass::Elem>(
static_cast<int>(l) | static_cast<int>(r)
);
}
enum class MyClass::Group {
first = Elem::A | Elem::B,
second = Elem::A | Elem::C,
};
Live demo
But the entire idea sorta goes against the concept of type-safe enum. Maybe you could just use the good old unsafe ones?
What about casting the values of Elem enum?
first = int(Elem::A) | int(Elem::B),
second = int(Elem::A) | int(Elem::C),
You need a static cast to the integral type corresponding to enumerator so there will be built-in operator |:
class MyClass
{
public: enum class Elem: unsigned int
{
A=1, B=2, C=4, D=8
};
public: enum class Group: unsigned int
{
first = static_cast<unsigned int>(Elem::A) | static_cast<unsigned int>(Elem::B)
, second = static_cast<unsigned int>(Elem::A) | static_cast<unsigned int>(Elem::C)
};
};

Translating from Java: How to define lambda members for enum types in C++?

In Java, it is possible to do the following for e.g. defining different variants of a simple calculation (in this case, inverted document frequency weights from the total number of documents D and the numbe rof documents that contain a term d):
package an.nlp.library.weights;
import java.util.function.BiFunction;
public enum IDF implements BiFunction<Long,Long,Double> {
UNARY( ( D, d ) -> 1d ),
IDF( ( D, d ) -> Math.log( D / d ) ),
IDFS( ( D, d ) -> Math.log1p( D / d ) ),
PIDF( ( D, d ) -> Math.log( D - d / d ) ),
;
private BiFunction<Long,Long,Double> func;
private IDF( BiFunction<Long,Long,Double> func ) {
this.func = func;
}
public Double weight( long D, long d ) {
return func.apply( D, d );
}
#Override
public Double apply( Long t, Long u ) {
return func.apply( t, u );
}
}
This can then be called from client code via, e.g.:
getIdf( long D, long d, IDF mode ) {
return mode.apply( D, d );
}
etc.
How would one accomplish the same in C++? i.e something like, calling something like:
// Obviously wrong, as I have no idea how to do it, hence the qeustion:
std::vector<double> getIdfWeights( long D, std::vector<double> ds, IDF mode ) {
return std::transform( ds.begin(), ds.end(), ds.begin(), IDF );
}
In other words, what would be the correct syntax to use to add 1) members to an enum type in C++ and 2) have those member values be lambdas that could then be called from somewhere else? From what I've been reading, apparently this is what enum classes are for, but I'm a C++ n00b so I don't entirelly understand how those work.
Enums in C++ are only integer values. They can't have members. enum class just removes integer conversions from the enum values.
You can do something similar with a class, e.g.
class Foo
{
int(*)(int) func;
int value;
public:
operator int() {
return value;
};
int operator()(int i) {
return func(i);
}
static constexpr Foo Value_A = { frob, 0 };
static constexpr Foo Value_B = { mung, 1 };
};

How does one use an enum class as a set of flags?

Let's say I have a set of flags and a class like this:
/// <summary>Options controlling a search for files.</summary>
enum class FindFilesOptions : unsigned char
{
LocalSearch = 0,
RecursiveSearch = 1,
IncludeDotDirectories = 2
};
class FindFiles : boost::noncopyable
{
/* omitted */
public:
FindFiles(std::wstring const& pattern, FindFilesOptions options);
/* omitted */
}
and I want a caller to be able to select more than one option:
FindFiles handle(Append(basicRootPath, L"*"),
FindFilesOptions::RecursiveSearch | FindFilesOptions::IncludeDotDirectories);
Is it possible to support this in a strongly-typed way with C++11 enum class, or do I have to revert to untyped enumerations?
(I know the caller could static_cast to the underlying type and static_cast back, but I don't want the caller to have to do that)
It is certainly possible to use enum classes for bitmaps. It is, unfortunately, a bit painful to do so: You need to define the necessary bit operations on your type. Below is an example how this could look like. It would be nice if the enum classes could derive from some other type which could live in a suitable namespace defining the necessary operator boilerplate code.
#include <iostream>
#include <type_traits>
enum class bitmap: unsigned char
{
a = 0x01,
b = 0x02,
c = 0x04
};
bitmap operator& (bitmap x, bitmap y)
{
typedef std::underlying_type<bitmap>::type uchar;
return bitmap(uchar(x) & uchar(y));
}
bitmap operator| (bitmap x, bitmap y)
{
typedef std::underlying_type<bitmap>::type uchar;
return bitmap(uchar(x) | uchar(y));
}
bitmap operator^ (bitmap x, bitmap y)
{
typedef std::underlying_type<bitmap>::type uchar;
return bitmap(uchar(x) ^ uchar(y));
}
bool test(bitmap x)
{
return std::underlying_type<bitmap>::type(x);
}
int main()
{
bitmap v = bitmap::a | bitmap::b;
if (test(v & bitmap::a)) {
std::cout << "a ";
}
if (test(v & bitmap::b)) {
std::cout << "b ";
}
if (test(v & bitmap::c)) {
std::cout << "c ";
}
std::cout << '\n';
}
Templates play well with enum class so you can define sets of operators that work on sets of similar enumeration types. The key is to use a traits template to specify what interface(s) each enumeration conforms/subscribes to.
As a start:
enum class mood_flag {
jumpy,
happy,
upset,
count // size of enumeration
};
template<>
struct enum_traits< mood_flag > {
static constexpr bool bit_index = true;
};
template< typename t >
struct flag_bits : std::bitset< static_cast< int >( t::count ) > {
flag_bits( t bit ) // implicit
{ this->set( static_cast< int >( bit ) ); }
// Should be explicit but I'm lazy to type:
flag_bits( typename flag_bits::bitset set )
: flag_bits::bitset( set ) {}
};
template< typename e >
typename std::enable_if< enum_traits< e >::bit_index,
flag_bits< e > >::type
operator | ( flag_bits< e > set, e next )
{ return set | flag_bits< e >( next ); }
template< typename e >
typename std::enable_if< enum_traits< e >::bit_index,
flag_bits< e > >::type
operator | ( e first, e next )
{ return flag_bits< e >( first ) | next; }
http://ideone.com/kJ271Z
GCC 4.9 reported that some implicit member functions were constexpr while I was getting this to compile, so the templates should probably be so as well.
This should probably also have a free function to_scalar or something which returns an unsigned integer type given either an individual flag or a flag_bits set.
How about defining FindFiles so that it takes std::initializer_list of FindFilesOptions.
void FindFiles(std::wstring const& pattern, std::initializer_list<FindFilesOptions> options)
{
auto has_option = [&](FindFilesOptions const option)
{
return std::find(std::begin(options), std::end(options), option) != std::end(options);
};
if (has_option(FindFilesOptions::LocalSearch))
{
// ...
}
if (has_option(FindFilesOptions::RecursiveSearch))
{
// ...
}
if (has_option(FindFilesOptions::IncludeDotDirectories))
{
// ...
}
}
Then you could call it like so:
FindFiles({}, {FindFilesOptions::RecursiveSearch, FindFilesOptions::IncludeDotDirectories});
The problem is not the explicit enum type but the class scope.
With C++11, enum as compile time constant loose a lot of interest compared to a bunch of constexpr when you need operate on the value ( bitwise operation, incrementation, etc)
If you don't care about performance, change your options to set<FindFilesOptions>!

Typedef a bitfield / mask in C++

I have this problem in C++: can I typedef a bitfield whose values come from an enum?
Code will be more explainatory:
typedef {
AUDIO = 0x01,
VIDEO = 0x02,
SUBTITLE = 0x04,
DATA = 0x08,
GUARD,
ALL = 0xFF
} my_enum_e;
// I'd like to replace 'unsigned int' by 'my_enum_e' or similar
int myFunction( unsigned int mask )
{
// code
}
// called like this:
myFunction( AUDIO|VIDEO|DATA );
In the prototype of the function, I'd like to use my_enum_e as an input value type, so that when exploring the code, you can immediately know which values you're supposed to put in there.
Now, changing the prototype to
int myFunction( my_enum_e mask );
makes the compiler whine about a cast error. I cant fix it by casting the function calls like this:
int myFunction( my_enum_e mask )
{
// code
}
myFunction( (my_enum_e)(VIDEO|AUDIO|DATA) );
But I find this quite horrible, and I'm not even sure it is legal (could it truncate the value??).
Do you have a solution?
Add an explicit overload for | and possibly other operators.
my_enum_e operator|(my_enum_e a, my_enum_e b)
{ return my_enum_e(unsigned(a)|unsigned(b)); }
One can write a macro that defines all needed operators for a given bitmask type.
#define BITMASK_OPERATORS(T) T operator|(T a, T b) { return T(unsigned(a)|unsigned(b)); } \
T operator^(T a, T b) ...
How about implementing a special function to deal with this:
template <typename Enum>
Enum bitField(unsigned bits) {
return static_cast<Enum>(bits);
}
It adds expressiveness to what you're doing:
myFunction(bitField<my_enum_e>(VIDEO|AUDIO|DATA));
If you want more sophistication, you can do this:
template <typename Enum>
struct BitField {
Enum value;
BitField(Enum value) : value(value) {}
BitField operator|(Enum more) {
return BitField(value | more);
}
BitField operator&(Enum more) {
return BitField(value & more);
}
BitField operator~() {
return BitField(~value);
}
operator Enum() {
return value;
}
}
Which will allow you to write
myFunction(BitField<my_enum_e>(VIDEO) | AUDIO | DATA);
As you performing a bitwise operation the compiler consider VIDEO|AUDIO|DATA as an integer value, so you have to cast it with *my_enum_e*.
I recommend that you look at this thread: Which Typesafe Enum in C++ Are You Using? - The mentioned implemention in the [Boost Vault] (filename enum_rev4.6.zip). 1 provides also the possibility to declare a BOOST_BITFIELD :
BOOST_BITFIELD(my_enum_e,
(AUDIO) (0x01)
(VIDEO) (0x02)
(SUBTITLE) (0x04)
(DATA) (0x08)
);
you can then declare your function:
int myFunction( const my_enum_e & in_enum )
{
if ( in_enum[AUDIO] ) ...
}
The usage is then
void callerFunction()
{
my_enum_e mask;
mask.set(my_enum_e::AUDIO);
mask.set(my_enum_e::VIDEO | my_enum_e::SUBTITLE );
cout << mask << " = " << hex << mask.value() << endl; // will print: AUDIO|VIDEO|SUBTITLE = 0x7
myFunction( mask );
}
The documentation of the api is not that good. But the packages comes with a test that shows several usages.
One way around it is to typedef int MY_FLAGS; and then #define all your values instead:
#define AUDIO 0x01 etc. That way the compiler won't moan and you still get types in your function calls:
int myFunction( MY_FLAGS mask );
myFunction( VIDEO|AUDIO|DATA );

Remove from a std::set<shared_ptr<T>> by shared_ptr<const T>

I have a a function, that essentially boils down to this (the part that I'm struggling with, ignoring the stuff that is actually happening)
class CellSorter
{
public:
bool operator()( std::shared_ptr<const Cell> a,
std::shared_ptr<const Cell> b ) const
{
return ( ( a->GetY() < b->GetY() ) ||
( a->GetY() == b->GetY() &&
a->GetX() < b->GetX() ) );
}
};
typedef std::set<std::shared_ptr<Cell>, CellSorter> Container;
MyClass::Container MyClass::DoSomething( std::shared_ptr<const Cell> c )
{
MyClass::Container N;
// assume that this code works to copy some stuff to N, blah blah blah
std::remove_copy_if( _grid.begin(), _grid.end(),
std::inserter( N, N.begin() ),
std::not1( CellIsNeighbor( c->GetX(), c->GetY() ) ) );
N.erase( c ); // ERROR
return N;
};
The problem is, gcc gives me an error:
/usr/include/c++/4.4/bits/shared_ptr.h:651:
error: invalid conversion from ‘const
Cell*’ to ‘Cell*’
I thought that this should not be casting the object "c" from shared_ptr<const Cell> to shared_ptr<Cell>, but somehow it is. I want c to point to a const Cell because there is no need to modify it. And the CellSorter shouldn't have a problem with const.
Any ideas as to why I can't do this or how to fix it?
It's because the shared_ptr in Container has type std::shared_ptr<Cell>. You are passing a std::shared_ptr<const Cell> to the erase() method. Different types. You can fix it by removing the const qualifier.
Apparently you can also use std::const_pointer_cast in this situation.
http://msdn.microsoft.com/en-us/library/bb982336.aspx