因此,我正在制作一个位掩码类,该类存储对std :: byte的引用作为成员以及单个位的索引,以允许访问该位的值并分配给该位。我还希望传递给std :: byte的值(可选)是const,并且如果它是const,则我希望类本身被视为const或至少确保可以更改std :: byte的基础值(例如赋值)不起作用。但是,我看不到没有复制粘贴代码的实现方法,我认为这太复杂了。有没有更简单的方法来解决这个问题?这是我当前的bitmask类代码:
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;
};
我想要的基本上是对其进行变体,其中块是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>;
因此,基本上,该类现在是一个模板,它根据所引用的字节是否为const来采用布尔值,并且我还为构造函数添加了模板参数推导提示,以便自动推导constness。operator=
如果is_const
是的话,我也只做工作false
。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句