为什么std::swap与std::bitset<n>内容不兼容?

8

考虑以下单元测试:

std::bitset<8> temp( "11010100" );
reverseBitSet( temp );
CPPUNIT_ASSERT( temp == std::bitset<8>( "00101011" ) );

这个实现方式可行:

template<size_t _Count> static inline void reverseBitSet( std::bitset<_Count>& bitset )
{
    bool val;
    for ( size_t pos = 0; pos < _Count/2; ++pos )
    {
        val = bitset[pos];
        bitset[pos] = bitset[_Count-pos-1];
        bitset[_Count-pos-1] = val;
    }
}

虽然这个不行:
template<size_t _Count> static inline void reverseBitSet( std::bitset<_Count>& bitset )
{
    for ( size_t pos = 0; pos < _Count/2; ++pos )
    {
        std::swap( bitset[pos], bitset[_Count-pos-1] );
    }
}

结果是“11011011”,而不是“00101011”。

为什么交换做错了?


bitset的operator[]返回一个代理对象。 - Piotr Skotnicki
1个回答

7

这个:

std::swap( bitset[pos], bitset[_Count-pos-1] );

如果实际编译失败。对于std::bitsetoperator[]不返回引用,而是返回代理对象。该代理对象不是左值,因此无法绑定到std::swap中的T&。我假设它能够编译,意味着你正在使用MSVC,它有一个扩展允许将临时对象绑定到非const引用 - 此时你可能只是交换代理而不是代理实际引用的内容。


注:名称_Count是由标准保留的,任何以_开头并后跟大写字母的名称也是如此。


1
@jpo38它并没有说它返回一个引用。它说它返回一个类型为std::bitset :: reference的对象(这确实有点令人困惑)。 - Barry
1
@jpo38 那个_reference_是std::bitset::reference,也就是答案中提到的代理对象。 - skypjack
明白了,名字有点让人困惑。你说得对,我正在使用MSVC进行开发。 - jpo38
2
提到关闭这个导致错误的功能所需的标志可能是一个好主意。 (/Za) - Yakk - Adam Nevraumont
1
实际上,vector<bool> 更奇怪 - 它有一个作用于 reference静态成员函数 swap。谁想出了这个混乱的东西? - T.C.
显示剩余8条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接