[英]Extracting and joining strings with boost::algorithms::join
我有一个特定结构的集合,我想将每个这些结构的字符串成员加入以分号分隔的列表中。 充分利用标准算法库和Boost,可以轻松解决问题:
std::transform
获取字符串的集合,然后 boost::algorithm::join
将它们连接在一起。 但是,仅复制字符串以供它们join
是很愚蠢的,因此我尝试在字符串周围使用reference_wrapper
作为std::transform
的输出。 相应的代码可以在这里看到:
struct IPAddress {
vector<uint8_t> binaryValue;
string stringValue;
}
// ---snip---
vector<IPAddress> addresses;
// Populate and manipulate the addresses vector
// ---snip---
// Join the list.
vector<reference_wrapper<string>> addressStrings(addresses.size());
transform(begin(addresses), end(addresses), begin(addressStrings),
[](const IPAddress& addr) {
return ref(addr.stringValue); // Expodes
});
return boost::algorithm::join(addressStrings, ";"); // Also explodes
提供给std::transform
的lambda无法编译,声称尽管两个reference_wrapper<string>
都已记录在案 ,但对reference_wrapper
的整个要点也没有匹配。
然后,如果我注释掉了transform
调用,则boost::algorithm::join
仍然会通过尝试调用reference_wrapper
的默认构造函数(没有)而不是string
来失败。
我是否缺少一些简单明了的东西,还是应该放弃并在迭代器中使用for
循环?
在增强范围的一点帮助下,您可以吃蛋糕并食用。
它消除了这种混合的麻烦:复杂之处在于,您想使用std::string const&
的中间集合,但是显然不适用于std::vector
。
因此,我们删除中间集合,而不是使用适应的视图 ( boost::adaptors::transformed
),并且也不需要lambda [¹],只需使用std::mem_fun
:观看Live on Coliru
#include <boost/algorithm/string.hpp>
#include <boost/range/adaptors.hpp>
#include <vector>
#include <string>
#include <functional>
struct IPAddress {
std::vector<uint8_t> binaryValue;
std::string stringValue;
};
std::string foo(std::vector<IPAddress> const& addresses)
{
using namespace boost::adaptors;
return boost::algorithm::join(
addresses | transformed(std::mem_fn(&IPAddress::stringValue)),
";");
}
#include <iostream>
int main()
{
std::vector<IPAddress> const addresses {
{ {}, "test1" },
{ {}, "test2" },
};
std::cout << foo(addresses);
}
打印
test1;test2
[¹]除非stringValue
是重载的成员函数
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.