寻找加入对象的字符串表示的惯用方法

时间:2015-12-03 21:18:55

标签: c++ boost idiomatic

考虑到我们有这个:

示例代码A:

struct parameter
{
    string name, value;
};

ostream& operator<<(ostream& out, const parameter& p)
{
    return out << p.name << "=" << p.value;
}

示例代码B:

auto seq = {
   parameter{ "language", "En" },
   parameter{ "q", "search+term" }
};

vector<string> tmp;
transform(begin(seq), end(seq), std::back_inserter(tmp),
    [](const auto& p) {
        ostringstream out;
        out << p;
        return out.str();
    });
auto result = boost::algorithm::join(tmp, "&");

有没有办法让示例代码B 更加惯用?我在计算tmp时试图避免使用result

最初我尝试直接在boost::algorithm::join上调用seq(这不起作用,因为加入仅适用于字符序列作为可连接元素。)

我还可以完全使用单个ostringstream和forego boost::algorithm::join(但这会附加额外的&),或者迭代元素数量,并避免在额外添加额外符号显式结束,或定义我自己的ostream迭代器(但is a lot of code to write)。

由于

2 个答案:

答案 0 :(得分:0)

如果我理解正确,并且缺少std :: transform的参数是insert_iterator到tmp,那么最简单的方法(最快!)就像下面这样:

std::ostringstream out;
for (auto&& item : seq)
     out << item << "&";
std::string str = out.str();
if (str.size() > 0)
   str.resize(str.size() - 1);

没有必要使用复杂的变换和丑陋的lambda语法,并且不需要创建一个临时向量来调用它上面的连接,并重新分配。

答案 1 :(得分:0)

对于更惯用的内容,您可以通过以下方式使用boost::adaptors::transformed

std::vector<parameter> seq = {{"language", "En"}, {"q", "search+term"}};
auto result = boost::algorithm::join(seq | 
   boost::adaptors::transformed([](parameter const &p){return p.name + "=" + p.value;}), 
   "&");

Live Demo

没有临时矢量,没有昂贵的字符串流。