因此,我正在创建一个位掩码类,它将对 std::byte 的引用存储为成员以及各个位的索引,以允许访问该位的值并分配给该位。我还希望传递的 std::byte 的值可以选择性地为 const,如果它是 const,我希望类本身被视为 const,或者至少确保可能更改的操作std::byte 的基础值(例如赋值)不起作用。但是,我没有找到一种无需复制粘贴代码即可实现它的方法,我认为这太复杂了。有没有更简单的方法来解决这个问题?这是我当前的位掩码类代码:
class bitmask
{
public:
bitmask(std::byte &chunk, std::uint_fast8_t index) noexcept
: _chunk(chunk), _index(index){};
bitmask(bitmask const &source) = default;
operator bool() const noexcept
{
return static_cast<bool>((_chunk >> (7 - _index)) & std::byte{1});
}
bitmask &operator=(bool val) noexcept
{
_chunk = ((_chunk & ~(std::byte{1} << (7 - _index))) |
(std::byte{val} << (7 - _index)));
return *this;
}
private:
std::byte &_chunk;
std::uint_fast8_t const _index;
};
我想要的是基本上制作它的变体,其中 chunk 是 const 引用并且赋值运算符不存在,而无需复制粘贴现有代码以避免重复。
PS:我不介意使用任何C++标准,包括C++20,只要它能够优雅地解决问题。
最佳答案
所以,尽管这里有一些非常好的答案,但我没有发现其中任何一个特别优雅,所以我决定更深入地研究并解决我自己的问题。请注意,这个解决方案并不完全是我的,最初是受到 @ildjarn 答案的启发,所以也支持他们。
这就是我最终解决问题的方法
// Class to mask reference to individual bit
template <bool is_const = false>
class bitmask
{
public:
using ChunkType = std::conditional_t<is_const, std::byte const, std::byte>;
bitmask(ChunkType &chunk, std::uint_fast8_t index) noexcept
: _chunk(chunk), _index(index){};
bitmask(bitmask const &source) = default;
operator bool() const noexcept
{
return static_cast<bool>((_chunk >> (7 - _index)) & std::byte{1});
}
template <typename = std::enable_if_t<!is_const>>
bitmask &operator=(bool val) noexcept
{
_chunk = ((_chunk & ~(std::byte{1} << (7 - _index))) |
(std::byte{val} << (7 - _index)));
return *this;
}
private:
ChunkType &_chunk;
std::uint_fast8_t const _index;
};
bitmask(std::byte &, std::uint_fast8_t)->bitmask<false>;
bitmask(std::byte const &, std::uint_fast8_t)->bitmask<true>;
所以基本上,该类现在是一个模板,它根据引用的字节是否为常量而采用 bool 值,并且我还为构造函数添加了模板参数推导提示,以便自动推导常量性。我还设置了 operator=
仅在 is_const
为 false
时才起作用。
关于const 和非常量引用成员的 C++ 类重写,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63203568/