演示问题:给定两个std::bitset<N>
,a
和b
检查a
和b
中是否设置了任何位。
这个问题有两个相当明显的解决方案。这很糟糕,因为它会创建一个新的临时位集,并复制各种地方的值,只是为了扔掉它们。
template <size_t N>
bool any_both_new_temp(const std::bitset<N>& a, const std::bitset<N>& b)
{
return (a & b).any();
}
这个解决方案很糟糕,因为它一次只有一点,这不太理想:
template <size_t N>
bool any_both_bit_by_bit(const std::bitset<N>& a, const std::bitset<N>& b)
{
for (size_t i = 0; i < N; ++i)
if (a[i] && b[i])
return true;
return false;
}
理想情况下,我可以执行以下操作:block_type
为uint32_t
或bitset
存储的任何类型:
template <size_t N>
bool any_both_by_block(const std::bitset<N>& a, const std::bitset<N>& b)
{
typedef std::bitset<N>::block_type block_type;
for (size_t i = 0; i < a.block_count(); ++i)
if (a.get_block(i) & b.get_block(i))
return true;
return false;
}
有没有简单的方法可以做到这一点?
答案 0 :(得分:6)
我在g++
中编译了第一个带优化的示例,它生成的代码与第三个解决方案相同。事实上,使用一个小的bitset(320位),它完全展开它。在没有调用函数的情况下,确保a
中b
和main
的内容未知,它实际上优化了整个事物(知道两者都是0)。
课程:编写明显可读的代码,让编译器处理它。
答案 1 :(得分:0)
你说你的第一种方法“复制价值各种各样的地方只是为了扔掉它们。”但实际上只有一个额外的值复制(当operator&
的结果返回到any_both_new_temp
时),并且可以通过使用引用而不是值来消除它:
template <size_t N>
bool any_both_new_temp(const std::bitset<N>& a, const std::bitset<N>& b)
{
std::bitset<N> tmp = a;
tmp &= b;
return tmp.any();
}
(但显然它仍会创建一个临时bitset
并将a
复制到其中。)