Я давно пишу на C ++, и, возможно, это потому, что мне не нужно делать это очень часто, но мне кажется, что мне не хватает перегрузки операторов.Я использую это время от времени, но мне никогда не нужно было делать то, что я хотел сделать в последнее время, и это было несколько проблематично.
class foo
{
public:
static const size_t ARRAY_SIZE = 100000;
uint8_t& operator[](const size_t& index) { return my_array[index >> 3]; }
// problematic equality operator
bool operator==(const size_t& index) const { return my_array[index >> 3] & (1 << (index & 7)); }
//
// Need an assignment operator to do:
// my_array[index >> 3] |= 1 << (index & 7);
// ^------------------^ might not needed as it's returned from [] operator
private:
std::array<uint8_t, (ARRAY_SIZE >> 3) + ((ARRAY_SIZE & 7) ? 1 : 0)> my_array;
};
Теперь, как вы можете видеть из вышесказанного, здесь делается следующее:возьмите число size_t и сохраните его в относительной битовой позиции.Так, например, 5 будет храниться в бите 4 байта 0, а 9 будет храниться в бите 1 байта 1 в массиве и т. Д.
Теперь оператор индекса работает нормально и возвращает правильный массив из массива, но это оставило проблему таких вещей:
if (foo[n]) // where n is a size_t integer representing a bit position
Затем меня осенило, что вышесказанное является сокращенной формой:
if (foo[n] == true)
, и поэтому я стал писатьвышеупомянутый оператор равенства, но по какой-то причине я не понимаю, оператор не вызывается.Я думал, что он будет вызван после оператора индекса или он не вызывается, потому что это больше не объект типа foo?Какой лучший способ это исправить?Это написать внешний оператор == и сделать его другом foo?
Да, и некоторые советы, касающиеся конструкции оператора присваивания, также будут оценены.Большое спасибо ...
РЕДАКТИРОВАТЬ: Спасибо за помощь людям.Я действительно думаю, что это невероятно сурово, чтобы опускать голос за вопрос о чем-то, что я не совсем понял.Это не похоже на глупый вопрос или что-то в этом роде, и если вы перечитаете мой оригинальный вопрос должным образом, я действительно задал вопрос, что foo может быть неправильным типом после оператора индекса, на что некоторые из вас указали.Во всяком случае, здесь немного больше контекста.У меня не было возможности должным образом изучить все великолепные ответы ...
Первоначально я написал оператор, подобный этому, который действительно возвращал правильный бит из массива.Что-то, на что кто-то уже указал.
bool operator[](const size_t index) const { return my_array[index >> 3] & (1 << (index & 7)); }
С чем у меня тогда была проблема - это устанавливать биты в массиве:
foo f;
if (f[3]) // this is fine
Но делать что-то вроде:
f[6] = true;
Я думаю, что то, на что я надеялся, было более элегантным способом сделать это, чем написать следующее: -
class Foo
{
public:
static const size_t MAX_LIST_SIZE = 100000;
bool get(const size_t index) const { return my_array[index >> 3] & (1 << (index & 7)); }
void set(const size_t index) { my_array[index >> 3] |= 1 << (index & 7); }
private:
std::array<uint8_t, ((MAX_LIST_SIZE >> 3) + ((MAX_LIST_SIZE & 7) ? 1 : 0))> my_array;
}
и затем использовать класс следующим образом:
Foo f
f.set(10);
if (f.get(10))
...
Я просто подумал, что было бы легче перегрузить операторов, но, на первый взгляд, это кажется более громоздким.(О, и кто-то спросил, почему я использовал uint8_t, а не bool, ну, это потому, что на этой конкретной платформе bool на самом деле 32бит!)