2016-08-30 95 views
1

假設我有一個std :: unordered_map。我需要一個遍歷映射鍵的迭代器,但需要引用C型char const *而不是std :: string。升壓::適配器看起來就像我需要爲第一部分的東西:獲取std :: string容器的C字符串迭代器

std::unordered_map<std::string, int> map{{"one",1},{"two",2}}; 
for (auto& str : map | boost::adaptors::map_keys) {...} 

我必須編寫自定義適配器的標準::與字符串> C-串變換或有另一種方式?

回答

3

首先,我質疑前提。使用std::string比使用char const*更有用。

這就是說,因爲你已經在使用的適配器,你只是想transformed

for (auto c_str : map | map_keys 
         | transformed(std::mem_fn(&std::string::c_str))) 
{ 
    ... 
} 
+0

我沒意識到你可以用這種方式進行改造,它只是我一直在尋找的東西。此外,你贏得使用自動。 – Mart

+0

要回答你的問題,我需要對迭代的對象進行標準佈局保證。 – Mart

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"; 
    } 
} 
+0

@巴里不是一個真正的問題。我想,更多的打字。 – sehe

+0

很遺憾,在C++之前的版本中沒有通用的lambda表達式。聖潔的Bjarne,看起來很漂亮! +1 – Mart

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); 
    } 
}