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
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;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With