2013-02-26 1 views
0

Я не уверен, возможно ли это, потому что, насколько мне известно, ссылки не могут ссылаться на отдельные биты целого числа, но мне любопытно узнать, есть ли техника, которая позволит использовать следующий эффект.Возможно ли перегрузить оператор индексирования [] для возврата битов из целого числа?

int z = 0x1234; 
z[0] = 1; //set the most significant bit of z. 
uint8_t bit = z[30] //get the index 30 bit of z, counting from the left. 

Если я не могу иметь z[0] = 1, мне интересно, если это по крайней мере, возможно, чтобы иметь возможность извлекать биты с помощью операции перегрузки.

+3

Перегрузка оператора не работает для встроенных типов, но вы можете создать свой собственный целочисленный класс и перегрузить [] для своего класса? – Saqlain

+1

Зачем использовать оператор индекса вообще? Это, несомненно, заслонит код, так как это не нормальное использование операторов индексирования. Лучше предоставить функцию, в которой четко указано, что она делает. –

ответ

5

Не напрямую. Вы можете написать обертку поверх int или использовать std::bitset.

+1

Могу ли я определить оболочку, которая ведет себя так, как int, кроме другого имени, и эта операция включена? – merlin2011

+2

@ merlin2011: Вы не можете точно подражать 'int'. Например, преобразование из 'int' в' long' является встроенным и, следовательно, может участвовать в цепочке конверсии, которая включает в себя преобразование, определяемое пользователем. Преобразование из вашего типа в 'long' будет определяться пользователем и, следовательно, будет работать против предела одного пользовательского преобразования в любой цепочке. Вы можете указать свой тип всем тем же операторам, что и 'int', AFAIK, это только преобразования, которые будут вести себя иначе, чем гарантированное поведение' int'. –

+1

@ merlin2011 Да, вы можете предоставить неявные преобразования из и в int для этой оболочки. Однако это редко бывает хорошей идеей, поскольку опечатки и логические ошибки, которые в противном случае были бы замечены компилятором, могли бы стать юридическим кодом и ввести труднодоступные ошибки. –

2

Вы не можете перегружать операторов для встроенных типов. Перегруженные операторы должны включать в себя, по меньшей мере, один пользовательский тип (т. Е. Тип класса или объединения).

0

Если вы собираетесь обернуть int, вы могли бы это сделать что-то вроде этого:

class bitval { 
    int &val; 
    unsigned int mask; 
    public: 
    bitval(int &i, int idx) : val(i), mask(((unsigned int)(INT_MAX) + 1) >> idx) {} 
    bitval &operator=(int i) { 
     if (i) { 
      val |= mask; 
     } else { 
      val &= ~mask; 
     } 
     return *this; 
    } 
    operator bool() const { 
     return val & mask; 
    } 
}; 

class bit { 
    int &val; 
    public: 
    bit(int &i) : val(i) {} 
    bitval operator[](int idx) { return bitval(val, idx); } 
}; 

Тогда синтаксис будет:

int z = 0x1234; 
bit(z)[0] = 1; 
uint8_t b = bit(z)[30]; 

Btw, C++ программисты обычно относятся к наименьший Значительный бит как бит 0, а не самый Значительный бит, поэтому mask(1 << idx) может сделать вещи менее запутанными для них.

Смежные вопросы