使用<<处理变量数据操作者

时间:2013-08-03 11:05:04

标签: c++ operator-overloading iostream

我有一段代码用于向远程端发送数据,它的行为有点像picojson,例如:

server::value::object obj;
obj["cmd"] = server::value("test");
obj["url"] = server::value(url);
...
obj["code"] = server::value(std::to_string(code));

server::value v(obj);
client.send_to_server(v.process());

只要有东西要发送,就会有这样的块。

这些行在我的项目中的许多地方使用,我正在考虑使用函数或<<运算符替换它,它应该能够处理变量参数。

A<<运营商版本就像:

Data d << "cmd" << "test"
       << "url" << url
       << ... << ...
       << "code" << code;
client.send_to_server(d);

这样做是个好主意吗?如何实现呢?

感谢。

2 个答案:

答案 0 :(得分:1)

设计这样的API并不是一个好主意,因为它非常容易出错。

一个看似相似的想法可以很好地处理输出流,原因很简单:您输入到输出流中的数据是统一处理的。除了流控制器控制输出的呈现方式之外,作为参数放入<<的任何内容都会成为输出的一部分。

您的API不同:奇数项目的处理方式与偶数项目不同。而且,发送奇数总数的操作数是错误的。如果由于某种原因您忘记在其中一行上放置字符串代码,则所有值都将在后续行中静默地成为代码。这样的API非常脆弱,所以我强烈推荐它。

我认为让用户成对添加项目的API可以更好地运行。如果您的编译器符合C ++ 11,那么您也可以使用uniform initialization语法:

Data d = {
    {"cmd", server::value("test")}
,   {"url", server::value(url)}
,   {"code", server::value(std::to_string(code))}
};

答案 1 :(得分:1)

我会用不同的方式写出来:

d << add_value("cmd", "test")
  << add_value("url", url)
  << add_value(..., ...)
  << add_value("code", code)
  ;

为什么呢?它更清晰,可以更好地控制类型。

所以你创建了一个类,比如__add_value_temp,它包含名称和值,一个函数add_value创建这个类,并写一个&lt;&lt;操作

Data &operator<<(Data &d, const __add_value_temp &val){
  d.add(val.name,val.val);
  return d;
}

更好 - 而不是__add_value_temp您可以使用std::pair,而使用std::make_pair代替add_value

Data &operator<<(Data &d, const std::pair<std::string,std::string> &val){
  d.add(val.first,val.second);
  return d;
}

...
Data d;
d << std::make_pair("cmd", "test")
  << std::make_pair("url", url)
  << std::make_pair(..., ...)
  << std::make_pair("code", code)
  ;

(最后一点:在operator<<的类型上编写模板pair可能很聪明,这样您就可以通过引用传递内容,通常可以避免不必要的复制)