8

一个演示问题:给定两个std::bitset<N>s,a并检查两个和b中是否设置了任何位。ab

这个问题有两个相当明显的解决方案。这很糟糕,因为它创建了一个新的临时位集,并将值复制到各种地方,只是为了把它们扔掉。

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_typeuint32_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;
}

有没有一种简单的方法可以做到这一点?

4

2 回答 2

6

我编译了您的第一个示例并进行了优化g++,它生成的代码与您的第三个解决方案相同。事实上,使用较小的位集(320 位)它完全展开它。没有调用函数来确保其中的内容ab未知main实际上优化了整个事物(知道两者都是 0)。

教训:编写明显的、可读的代码,让编译器处理它。

于 2011-12-02T00:43:14.577 回答
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到其中。)

于 2011-12-02T00:42:02.523 回答