如何使用读写工具重载下标运算符?

How to overload subscript operator with both read and write facility?

以下代码未编译。

#include <bitset>
#include <iostream>

class Bits
{
public:
    std::bitset<4> bits;
public:
    Bits();
    Bits(Bits & b);
    Bits & operator = (Bits & b);
    bool   operator [] (int index) const; // For reading
    bool & operator [] (int index);       // For writing
};

Bits :: Bits() { }
Bits :: Bits(Bits & b)
{
    *this = b;
}

Bits &  Bits :: operator = (Bits & b)
{
    bits[0] = b.bits[0];
    bits[1] = b.bits[1];
    bits[2] = b.bits[2];
    bits[3] = b.bits[3];

    return *this;
}

bool Bits::operator [] (int index) const
{
   return bits[index];
}

bool & Bits::operator [] (int index)
{
   return bits[index];
}

int main()
{
    Bits bits;

    bits[0] = true;
    bits[1] = false;
    bits[2] = true;
    bits[3] = false;

    return 0;
}

错误:

1>------ Rebuild All started: Project: SubscriptOperatorOverloading, Configuration: Debug Win32 ------
1>Deleting intermediate and output files for project 'SubscriptOperatorOverloading', configuration 'Debug|Win32'
1>Compiling...
1>Bits.cpp
1>e:\developer-workspace\subscriptoperatoroverloading\subscriptoperatoroverloading\bits.cpp(39) : error C2440: 'return' : cannot convert from 'std::bitset<_Bits>::reference' to 'bool &'
1>        with
1>        [
1>            _Bits=4
1>        ]
1>Build log was saved at "file://e:\Developer-Workspace\SubscriptOperatorOverloading\SubscriptOperatorOverloading\Debug\BuildLog.htm"
1>SubscriptOperatorOverloading - 1 error(s), 0 warning(s)
========== Rebuild All: 0 succeeded, 1 failed, 0 skipped ==========

Return std::bitset<4>::reference 而不是 bool&.

std::bitset<4>::reference 不是 bool& 的原因是(在合理的实现中)bitset 的元素是 计算值 而不是比对象;读取元素需要计算,写入元素需要计算,因此 operator[] 的 return 值不可能是普通引用。

因此,bitset<N>::reference需要是一个proxy对象;它可以转换为 bool(进行正确的计算)并具有赋值运算符(进行正确的计算)。