假设我有3个bool
类型值
bool canwalk=true;
bool cantalk=false;
bool caneat=false;
我想设置bitset
表示三个
std::bitset<3> foo;
如何使用布尔值构造bitset
?
我想做这样的事情
std::bitset<3> foo(canWalk,cantalk,caneat); //giving me 100
答案 0 :(得分:2)
引入一个新的api,它可以为你提供bitset在参数中接受的字符串输入。
更通用,建议使用bool数组或sudo apt-get install gtk2.0
sudo apt-get install build-essential libgtk2.0-dev
去掉getString()中的这些变量参数
[std::vector<bool>][1]
现在可以将bitset定义为:
inline std::string getString(bool canwalk, bool canTalk, bool canEat)
{
std::stringstream input;
str << canwalk?1:0 << cantalk?1:0 << caneat?1:0;
return input.str();
}
答案 1 :(得分:2)
以Shivendra Agarwal为例,但使用接收unsigned long long
的构造函数,我提出了以下可变参数模板函数(更通用)
template <typename ... Args>
unsigned long long getULL (Args ... as)
{
using unused = int[];
unsigned long long ret { 0ULL };
(void) unused { 0, (ret <<= 1, ret |= (as ? 1ULL : 0ULL), 0)... };
return ret;
}
允许foo
的初始化如下
std::bitset<3> foo{ getULL(canwalk, cantalk, caneat) };
仅当std::bitset
的维度不大于unsigned long long
中的位数(3
确定是安全的)时,此方法才有效。
以下是一个完整的工作示例
#include <bitset>
#include <iostream>
template <typename ... Args>
unsigned long long getULL (Args ... as)
{
using unused = int[];
unsigned long long ret { 0ULL };
(void) unused { 0, (ret <<= 1, ret |= (as ? 1ULL : 0ULL), 0)... };
return ret;
}
int main()
{
bool canwalk=true;
bool cantalk=false;
bool caneat=false;
std::bitset<3> foo{ getULL(canwalk, cantalk, caneat) };
std::cout << foo << std::endl;
}
答案 2 :(得分:1)
您基本上需要一个构建器,它将从您的布尔集构建一个初始值,以传递给std :: bitset的构造函数。您可以通过可变参数模板在编译时(而不是运行时)执行此操作,如下所示:
template <unsigned long long initialValue>
constexpr unsigned long long bitset_value_builder_impl() { return initialValue; }
template <unsigned long long initialValue, typename First, typename ... Args>
constexpr unsigned long long bitset_value_builder_impl(First &&first, Args &&...args) {
return first ?
bitset_value_builder_impl< (initialValue | (1UL<<sizeof...(args)) ), Args...>(std::forward<Args>(args)...) :
bitset_value_builder_impl< (initialValue & ~(1UL<<sizeof...(args)) ), Args...>(std::forward<Args>(args)...);
}
template <typename First, typename ... Args>
constexpr unsigned long long bitset_value_builder(First &&first, Args &&...args) {
return bitset_value_builder_impl<0, First, Args...>(std::forward<First>(first), std::forward<Args>(args)...);
}
int main()
{
bool canwalk=true;
bool cantalk=false;
bool caneat=false;
std::bitset<3> bits{bitset_value_builder(canwalk, cantalk, caneat)};
std::cout << bits << std::endl; //100
}
答案 3 :(得分:1)
恕我直言,类型
的初始化std::bitset<3> foo(canWalk, cantalk, caneat);
是危险的(容易出错),因为要求std::bitset
(示例中)3
的模板参数对应于初始化的参数个数。
我建议创建一个&#34; make&#34; function(遵循std::pair()
,std::tuple()
,std::make_unique()
,std::make_shared
的合并示例,其中参数的类型和数量可以修复返回的类型。
所以我建议使用以下makeBitSet()
函数返回std::bitset<N>
,其中N
是参数的数量
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;
}
该功能可以按如下方式使用
std::bitset<3> foo{ makeBitSet(canwalk, cantalk, caneat) };
但也(更好,恕我直言),使用C ++ 11 auto
,
auto foo = makeBitSet(canwalk, cantalk, caneat);
请注意,从C ++ 14开始,makeBitSet()
可以使用返回的auto
类型
template <typename ... Args>
auto makeBitSet (Args ... as)
{
// ...
避免恼人的std::bitset<sizeof...(Args)>
冗余。
此外,从C ++ 17开始,您可以使用模板折叠,丢弃unused
数组(以及相应的using
声明),makeBitSet()
可以简化为[编辑:根据Mooing Duck的建议修改,改善表现(谢谢!)]
template <typename ... Args>
auto makeBitSet (Args ... as)
{
std::bitset<sizeof...(Args)> ret;
std::size_t ui { ret.size() };
( ret.set(--ui, as), ... );
return ret;
}
以下是一个完整的C ++ 11示例
#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;
}