使用与BITSet的initializer_list
Using an initializer_list with bitset
是否有一种使用initializer_list
构造bitset
?
例如,我想做:
const auto msb = false;
const auto b = true;
const auto lsb = false;
const bitset<3> foo = {msb, b, lsb};
但是,当我尝试一下时,我会得到:
错误:无法从'&lt; brace封闭的初始器列表中转换
{msb, b, lsb}
&gt;'到const std::bitset<3u>
我是否必须使用Shifts来构建unsigned long
来初始化foo
,或者有办法做到这一点?
没有构造函数可以直接从启动器列表中构造bitset。您需要一个功能:
#include <bitset>
#include <initializer_list>
#include <iostream>
auto to_bitset(std::initializer_list<bool> il)
{
using ul = unsigned long;
auto bits = ul(0);
if (il.size())
{
auto mask = ul(1) << (il.size() - 1);
for (auto b : il) {
if (b) {
bits |= mask;
}
mask >>= 1;
}
}
return std::bitset<3> { bits };
}
int main()
{
auto bs = to_bitset({true, false, true});
std::cout << bs << std::endl;
}
预期结果:
101
如评论中提到的,也可以使用variadic版本。
#include <bitset>
#include <iostream>
#include <utility>
namespace detail {
template<std::size_t...Is, class Tuple>
auto to_bitset(std::index_sequence<Is...>, Tuple&& tuple)
{
static constexpr auto size = sizeof...(Is);
using expand = int[];
unsigned long bits = 0;
void(expand {
0,
((bits |= std::get<Is>(tuple) ? 1ul << (size - Is - 1) : 0),0)...
});
return std::bitset<size>(bits);
}
}
template<class...Bools>
auto to_bitset(Bools&&...bools)
{
return detail::to_bitset(std::make_index_sequence<sizeof...(Bools)>(),
std::make_tuple(bool(bools)...));
}
int main()
{
auto bs = to_bitset(true, false, true);
std::cout << bs << std::endl;
}
使用BITSet的字符串表示形式的简短示例。在某些情况下,此实施可能不是最佳的。
template <typename ... args>
auto make_bitset(args... bools) -> std::bitset<sizeof...(bools)>
{
char data[] = {bools ? '1':'0'...};
return std::bitset<sizeof...(bools)>(data, sizeof...(bools));
}
int main()
{
std::cout << make_bitset(1,1,0,0,1,0, 1) << "n";
std::cout << make_bitset(1,1,1) << "n";
std::cout << make_bitset(0,0,0,0) << "n";
}
使用"几乎递归"调用的另一个实现:
template <size_t N, int pos>
void init_bitset(std::bitset<N>&){}
template <size_t N, int pos = 0, typename ...Bits>
void init_bitset(std::bitset<N>& bitset, bool head, Bits ...tail)
{
bitset.set(pos, head);
init_bitset<N, pos + 1>(bitset, tail...);
}
template <typename ... args>
auto make_bitset(args... bools) -> std::bitset<sizeof...(bools)>
{
std::bitset<sizeof...(bools)> bitset;
init_bitset(bitset, bools...);
return bitset;
}
int main()
{
std::cout << make_bitset(1,1,0,0,1,0, 1) << "n";
std::cout << make_bitset(1,1,1) << "n";
std::cout << make_bitset(0,0,0,0) << "n";
}
有关详细信息,请参见编译器资源管理器https://godbolt.org/g/9z2hza
使用C 17
的奖励版本template <typename ... args>
auto make_bitset(args... bools)
{
unsigned n = 0;
static_assert( sizeof...(bools) <= sizeof(n) * 8, "overflow" );
((n = n * 2 + static_cast<bool>(bools)), ...);
return std::bitset<sizeof...(bools)>(n);
}
相关文章:
- 使用std::multimap迭代器创建std::list
- 来自 std::list 的迭代器 .end() 按预期返回"0xcdcdcdcdcdcdcdcd"但 .begin()
- 如何在 C 中正确使用 libiconv 使其不会报告"Arg list too long"?
- C++中带有List类的迭代器Segfault
- 使用"std::unordereded_map"映射到"std::list"对象
- GCC对可能有效的代码抛出init list生存期警告
- 使用std::list创建循环链表
- C2664 无法从'initializer list'转换参数
- 使用 std::min "no matching function for call to ‘min(<brace-enclosed initializer list>)’"时出错
- 在C++中标记化"Braced Initializer List"样式字符串(使用 Boost?
- "默认参数":无法从'initializer list'转换为'std::initializer_list'
- 无法从'initializer-list'转换为用户控制器
- 如何修复<function-style-cast>错误:无法从'initializer list'转换为asdending比较<W>(模板函子)
- 递归调用中出现错误"[Error] expression list treated as compound expression in initializer [-fpermissive]"
- VS2015无法从'initializer list'转换为'std::string'错误
- 编译器错误:"Non-aggregates cannot be initialized with initializer list."
- 无法转换...从 '<brace-enclosed initializer list>' 到 地图
- 无法将'<brace-enclosed initializer list>'转换为'double'作为回报
- <function-style-cast> 错误:无法从'initializer list'转换为'std::thread'
- initializer语言 - list不能转换为const margin *