假设我有一个std :: unordered_map。我需要一个迭代器,它遍历地图的键但是取消引用C风格的char const *而不是std :: string。 Boost :: adapter看起来就像我第一部分需要的那样:
std::unordered_map<std::string, int> map{{"one",1},{"two",2}};
for (auto& str : map | boost::adaptors::map_keys) {...}
我是否必须为std :: string-&gt; C-string转换编写自定义适配器,还是有另一种方式?
答案 0 :(得分:3)
首先,我质疑这个前提。使用std::string
比使用char const*
更有用。
那就是说,既然您已经在使用适配器,那么您只需要transformed
:
for (auto c_str : map | map_keys
| transformed(std::mem_fn(&std::string::c_str)))
{
...
}
答案 1 :(得分:3)
最简单的答案:
#include <unordered_map>
#include <boost/range/adaptors.hpp>
#include <string>
#include <iostream>
using namespace boost::adaptors;
int main() {
std::unordered_map<std::string, int> map{{"one",1},{"two",2}};
for (char const* sz : map
| map_keys
| transformed(std::mem_fn(&std::string::c_str))
) {
std::cout << sz << "\n";
}
}
我的首选:
#include <unordered_map>
#include <boost/range/adaptors.hpp>
#include <string>
#include <iostream>
using namespace boost::adaptors;
int main() {
std::unordered_map<std::string, int> map{{"one",1},{"two",2}};
for (char const* sz : map | transformed([](auto const& p) { return p.first.c_str(); }))
{
std::cout << sz << "\n";
}
}
答案 2 :(得分:0)
如果你没有提升方便,你可以通过派生地图的迭代器手动滚动它:
#include <unordered_map>
#include <string>
#include <stdio.h>
struct cstrofkey
: std::unordered_map<std::string, int>::const_iterator
{
using base_class = std::unordered_map<std::string, int>::const_iterator;
using value_type = const char*;
cstrofkey(base_class iter) : base_class(iter) {}
auto operator*() const
{
return (base_class::operator*()).first.c_str();
}
};
struct cstrkeyrange
{
cstrkeyrange(const std::unordered_map<std::string, int>& map)
: _begin(map.cbegin()), _end(map.cend())
{};
cstrofkey begin() const { return _begin; }
cstrofkey end() const { return _end; }
cstrofkey _begin, _end;
};
int main()
{
std::unordered_map<std::string, int> map{{"one",1},{"two",2}};
for (auto str : cstrkeyrange(map)) {
printf("%s\n", str);
}
}