我有一个特定结构的集合,我想将这些结构的一个字符串成员加入到一个分号分隔的列表中。充分利用标准算法库和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循环?
发布于 2014-08-07 21:54:14
有了一些帮助,从提升范围,你可以吃你的蛋糕。
它从这种混合中消除了刺痛:复杂的是,您想要使用std::string const&的中间集合,但是,很明显,这并不适用于std::vector。
因此,我们删除中间集合,而使用适配视图(boost::adaptors::transformed),并且,也不需要使用lambda,只需使用std::mem_fun:参阅住在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是重载的成员函数
https://stackoverflow.com/questions/25189971
复制相似问题