Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

best way to set a bitset with boolean values

Tags:

c++

c++11

bitset

Suppose I have 3 bool type values

bool canwalk=true;
bool cantalk=false;
bool caneat=false;

I would like to set a bitset denoting the three

std::bitset<3> foo;

How can I construct a bitset using the boolean values? I want to do something like this

 std::bitset<3> foo(canWalk,cantalk,caneat); //giving me 100
like image 728
Rajeshwar Avatar asked Oct 24 '25 15:10

Rajeshwar


1 Answers

IMHO, an initialization of type

std::bitset<3> foo(canWalk, cantalk, caneat);

is dangerous (error prone) because require that the template argument of std::bitset (3, in the example) correspond to the number of argument of the initialization.

I propose the creation of a "make" function (following the consolidated example of std::pair(), std::tuple(), std::make_unique(), std::make_shared) where the type and the number of arguments fix the returned type.

So I propose the following makeBitSet() function that return a std::bitset<N> where N is the number of the arguments

template <typename ... Args>
std::bitset<sizeof...(Args)> makeBitSet (Args ... as)
 {
   using unused = bool[];

   std::bitset<sizeof...(Args)>  ret;

   std::size_t ui { ret.size() };

   (void) unused { true, (ret.set(--ui, as), true)... };

   return ret;
 }

The function can be used as follows

std::bitset<3> foo{ makeBitSet(canwalk, cantalk, caneat) };

but also (better, IMHO), using the C++11 auto,

auto foo = makeBitSet(canwalk, cantalk, caneat);

Observe that, starting from C++14, makeBitSet() can use the returning auto type

template <typename ... Args>
auto makeBitSet (Args ... as)
 {
   // ...

avoiding the annoying std::bitset<sizeof...(Args)> redundancy.

Moreover, starting from C++17, you can use template folding and, throwing away the unused array (and the corresponding using declaration), the makeBitSet() can be simplified as [EDIT: modified, to improve performances, following a suggestion from Mooing Duck (thanks!)]

template <typename ... Args>
auto makeBitSet (Args ... as)
 {
   std::bitset<sizeof...(Args)>  ret;

   std::size_t ui { ret.size() };

   ( ret.set(--ui, as), ... );

   return ret;
 }

The following is a full working C++11 example

#include <bitset>
#include <iostream>

template <typename ... Args>
std::bitset<sizeof...(Args)> makeBitSet (Args ... as)
 {
   using unused = bool[];

   std::bitset<sizeof...(Args)>  ret;

   std::size_t ui { ret.size() };

   (void) unused { true, (ret.set(--ui, as), true)... };

   return ret;
 }

int main()
 {
   bool canwalk { true  };
   bool cantalk { false };
   bool caneat  { false };

   auto foo = makeBitSet(canwalk, cantalk, caneat);

   std::cout << foo << std::endl;
 }
like image 146
max66 Avatar answered Oct 26 '25 06:10

max66



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!