我试图做一个替代点。主要动机是拥有可以轻松序列化/反序列化的东西。所以我创建了一个位域类。
template <typename T, size_t ...SIZES>
struct BitField {
using Type = T;
template <size_t I>
void set (T v)
{
...
}
template <size_t I>
T get ()
{
...
}
T value_;
};
所以可以像下面这样创建一个位文件:
BitField<uint16_t, 4, 3, 9> field; // creates a 4bit, 3bit and 9bit field in a uint16_t
但是没有很好的方法来设置和获得该领域。通过上面的接口,我们可以通过索引获取和设置每个字段。
field.get<0>()
field.set<0>(10)
我想给它一个简单的语法,比如变量访问和赋值。而且我不清楚我是如何做到的。我创建了一个Field类。我们的想法是建立一个联盟:
struct Mpls {
using BF = BitField<uint32_t, 20, 3, 1, 8>;
union Label {
BF _bf;
Field<0, BF> _label; // this will act like a variable
Field<1, BF> _exp;
Field<2, BF> _eos;
Field<3, BF> _ttl;
} label;
};
Field类定义如下。但我不知道这是否严格合法?
template <size_t I, typename BF>
struct Field {
using Type = typename BF::Type;
void operator = (Type v)
{
// typecast 'this' to 'BitField class' and here is where I have doubt if this is okay.
((BF *)this)->template set<I>(v);
}
operator Type()
{
return ((BF *)this)->template get<I>();
}
};
我可以像这样设置字段。
mpls.label._ttl = 0xff;
这很有效。但这样做可以吗?