通过 operator[] 进行按位操作
bitwise manipulation via operator[]
我正在编写一个简单的位集包装器来轻松高效地 set、clear 和 read 来自 8 位整数的位。我会通过 operator[]
执行这三个操作,但我被卡住了,老实说,我不确定在不损失性能的情况下是否可行(对我的目的来说非常重要)。
#include <stdint.h>
#include <iostream>
class BitMask {
private:
uint8_t mask;
public:
inline void set(int bit) { mask |= 1 << bit; } // deprecated
inline void clear(int bit) { mask &= ~(1 << bit); } // deprecated
inline int read(int bit) { return (mask >> bit) & 1; } // deprecated
bool operator[](int bit) const { return (mask >> bit) & 1; } // new way to read
??? // new way to write
friend std::ostream& operator<<(std::ostream& os, const BitMask& bitmask) {
for (int bit = 0; bit < 8; ++bit)
os << ((bitmask.mask >> bit) & 1 ? "1" : "0");
return os;
}
};
int main() {
BitMask bitmask1;
bitmask1.set(3);
bitmask1.clear(3);
bitmask1.read(3);
std::cout << bitmask1;
BitMask bitmask2;
bitmask2[3] = 1; // set
bitmask2[3] = 0; // clear
bitmask2[3]; // read
std::cout << bitmask2;
}
有什么想法吗?
一种方法(唯一的方法?)是 return 来自您的 operator[]
的代理对象,它将为您的位保存索引,这样您将为您的代理对象分配新值将更改适当的 BitMask 位。例如,请看这里:Vector, proxy class and dot operator in C++
至于性能 - 这完全取决于编译器将如何优化您的代码,如果您的代理 class 只有内联方法,那么它应该很快。
下面是如何修复代码的示例:
#include <stdint.h>
#include <iostream>
class BitMask {
private:
uint8_t mask;
public:
inline void set(int bit) { mask |= 1 << bit; } // deprecated
inline void clear(int bit) { mask &= ~(1 << bit); } // deprecated
inline int read(int bit) const { return (mask >> bit) & 1; } // deprecated
struct proxy_bit
{
BitMask& bitmask;
int index;
proxy_bit(BitMask& p_bitmask, int p_index) : bitmask(p_bitmask), index(p_index) {}
proxy_bit& operator=(int rhs) {
if (rhs)
bitmask.set(index);
else
bitmask.clear(index);
return *this;
}
operator int() {
return bitmask.read(index);
}
};
proxy_bit operator[](int bit) { return proxy_bit(*this, bit); } // new way to read
int operator[](int bit) const { return read(bit); } // new way to read
friend std::ostream& operator<<(std::ostream& os, const BitMask& bitmask) {
for (int bit = 0; bit < 8; ++bit)
os << ((bitmask.mask >> bit) & 1 ? "1" : "0");
return os;
}
};
int main() {
BitMask bitmask1;
bitmask1.set(3);
bitmask1.clear(3);
bitmask1.read(3);
std::cout << bitmask1 << std::endl;
BitMask bitmask2;
bitmask2[3] = 1; // set
bitmask2[3] = 0; // clear
bitmask2[3]; // read
std::cout << bitmask2 << std::endl;
const BitMask bitmask3;
if (bitmask3[3]) {}
//bitmask3[3] = 1; // compile error - OK!
}
我正在编写一个简单的位集包装器来轻松高效地 set、clear 和 read 来自 8 位整数的位。我会通过 operator[]
执行这三个操作,但我被卡住了,老实说,我不确定在不损失性能的情况下是否可行(对我的目的来说非常重要)。
#include <stdint.h>
#include <iostream>
class BitMask {
private:
uint8_t mask;
public:
inline void set(int bit) { mask |= 1 << bit; } // deprecated
inline void clear(int bit) { mask &= ~(1 << bit); } // deprecated
inline int read(int bit) { return (mask >> bit) & 1; } // deprecated
bool operator[](int bit) const { return (mask >> bit) & 1; } // new way to read
??? // new way to write
friend std::ostream& operator<<(std::ostream& os, const BitMask& bitmask) {
for (int bit = 0; bit < 8; ++bit)
os << ((bitmask.mask >> bit) & 1 ? "1" : "0");
return os;
}
};
int main() {
BitMask bitmask1;
bitmask1.set(3);
bitmask1.clear(3);
bitmask1.read(3);
std::cout << bitmask1;
BitMask bitmask2;
bitmask2[3] = 1; // set
bitmask2[3] = 0; // clear
bitmask2[3]; // read
std::cout << bitmask2;
}
有什么想法吗?
一种方法(唯一的方法?)是 return 来自您的 operator[]
的代理对象,它将为您的位保存索引,这样您将为您的代理对象分配新值将更改适当的 BitMask 位。例如,请看这里:Vector, proxy class and dot operator in C++
至于性能 - 这完全取决于编译器将如何优化您的代码,如果您的代理 class 只有内联方法,那么它应该很快。
下面是如何修复代码的示例:
#include <stdint.h>
#include <iostream>
class BitMask {
private:
uint8_t mask;
public:
inline void set(int bit) { mask |= 1 << bit; } // deprecated
inline void clear(int bit) { mask &= ~(1 << bit); } // deprecated
inline int read(int bit) const { return (mask >> bit) & 1; } // deprecated
struct proxy_bit
{
BitMask& bitmask;
int index;
proxy_bit(BitMask& p_bitmask, int p_index) : bitmask(p_bitmask), index(p_index) {}
proxy_bit& operator=(int rhs) {
if (rhs)
bitmask.set(index);
else
bitmask.clear(index);
return *this;
}
operator int() {
return bitmask.read(index);
}
};
proxy_bit operator[](int bit) { return proxy_bit(*this, bit); } // new way to read
int operator[](int bit) const { return read(bit); } // new way to read
friend std::ostream& operator<<(std::ostream& os, const BitMask& bitmask) {
for (int bit = 0; bit < 8; ++bit)
os << ((bitmask.mask >> bit) & 1 ? "1" : "0");
return os;
}
};
int main() {
BitMask bitmask1;
bitmask1.set(3);
bitmask1.clear(3);
bitmask1.read(3);
std::cout << bitmask1 << std::endl;
BitMask bitmask2;
bitmask2[3] = 1; // set
bitmask2[3] = 0; // clear
bitmask2[3]; // read
std::cout << bitmask2 << std::endl;
const BitMask bitmask3;
if (bitmask3[3]) {}
//bitmask3[3] = 1; // compile error - OK!
}