封装“可选”的最佳方式C++ 中结构体中的字段通常如何?
我有很多具体结构,我想将字段指定为可选(存在或不存在)。只是想知道人们有什么想法来实现这一目标。这是一个示例结构(字段也可以是其他结构,甚至是结构的向量):
struct LogonMessage_t
{
Header_t header; // this points to another struct containing all primitives
std::string username;
std::string password;
std::vector<LogonOption_t> LogonOptions;
int subaccountid;
std::string Text;
}
我想将所有字段默认为不存在并一一启用它们,也许在它们的设置器中。由于这些结构是生成的,因此最好使用通用方法。
到目前为止我的想法是:
- 指示字段是否设置的字段位图
- 使用哨兵值(“\0”表示 std::string,-1 表示 int,-1.0f 表示 float
- 封装每个字段的某种模板容器/代理字段来指示它是否已设置,有什么想法吗?我认为这可能是最好的方法
,使用映射或其他 STL 容器来封装字段在这里不起作用,它们需要是具体的结构。
I have many concrete-structs and I want to designate fields as optional (present or not-present). Just wondering what ideas people have for achieving this. Here is an example struct (fields can be other structs as well, even vectors of structs):
struct LogonMessage_t
{
Header_t header; // this points to another struct containing all primitives
std::string username;
std::string password;
std::vector<LogonOption_t> LogonOptions;
int subaccountid;
std::string Text;
}
I'd like to default all fields to not-present and enable them one by one, perhaps in their setters. Since these structs are generated, a generic method would be preferable.
My ideas so far are:
- Bitmap of fields indicating if a field is set or not
- Use sentinel values ("\0" for std::string, -1 for int, -1.0f for float
- Some kind of template container/proxy encapsulating each field to indicate if it's set or not, any ideas? I think this might be the best approach.
Btw, using maps or other STL containers to encapsulate the fields won't work here, they need to be concrete structs.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
听起来你想要提升。可选。
Sounds like you want boost.optional.
保持简单。使用标志成员变量,您可以通过对常量进行或操作来设置该变量,并通过对它们进行检查。
哨兵值的问题是选择不合法的字段值(现在和将来)。
Keep it simple. Use a flag member variable that you can set by or-ing constants together and inspect by and-ing them.
Problem with sentinel values is choosing ones that are not also legal field values (now and in the future).
字符串和向量都有一个空的默认状态,您可以使用
if (username.empty())
等进行测试。对于
subaccountid
我猜测 0 是类似的空值。否则-1也可以。Both string and vector has an empty default state, which you can test for with
if (username.empty())
etc.For a
subaccountid
I would guess that 0 would be a similar empty value. Otherwise -1 could be ok.我会用一个标志。我可以向您建议两种方法,一种将值保留在堆上,一种保留在堆栈上。
在第一个中,您使用 std::pair ,第一个字段是存在标志。
第二种方法是通过 boost::shard_ptr,如果指针指向 0,则该字段不存在。
在这两种情况下,我的建议是不要直接访问 Value 中的元素,而是使用几个函数。
const 值&值() const { 返回 }
价值& value() { return }
弗朗西斯科
I'd use one a flag. I can propose you two method, one keeping the value on the heap and one on the stack.
In the first you use a std::pair and the first field is the existence-flag.
The second approach is via a boost::shard_ptr, if pointer points to 0 the field is not existing.
In both the cases my advice is not to access directly to the element in Value but using instead a couple of functions.
const Value& value() const { return }
Value& value() { return }
francesco