2014-10-28 170 views
2

我想用包含在std::vector对象中的键初始化一个std::map对象。std :: map初始化std :: vector

std::vector<char> mykeys { 'a', 'b', 'c' ]; 
std::map<char, int> myMap; 

我该怎么做没有循环?

我可以添加默认值到我的int

+1

价值是什么? – 2014-10-28 10:58:54

+0

您可以使用内部使用循环的std库函数吗? – juanchopanza 2014-10-28 10:59:30

+0

int值为0. 是的我可以使用std lib函数,但我问自己是否有一种自动方法来构造带有向量的地图? – hao 2014-10-28 11:00:45

回答

12

如果没有一个明确的循环

std::transform(std::begin(mykeys), std::end(mykeys), 
       std::inserter(myMap, myMap.end()), 
       [] (char c) {return std::make_pair(c, 0);}); 

Demo

一系列为基础的循环会更性感了,所以使用,如果可能的:

for (auto c : mykeys) 
    myMap.emplace(c, 0); 
+9

这是我感觉循环更具可读性的那些时刻之一。 – 2014-10-28 11:02:21

2

没有,你不能这样做,没有环或等同结构。 (句号)你可以在一些函数中隐藏循环,比如std::transform(),但是不能避免。此外,编译器经过良好训练以优化循环(因为它们是无处不在的),所以没有理由避免它们。

0

如果没有循环,你不能这样做。你可以做的是隐藏在一个标准算法下一个循环,因为你需要char类型的对象转换为std::map<char, int>::value_type类型的对象,表示本身std::pair<const char, int>

例如

#include <iostream> 
#include <vector> 
#include <map> 
#include <iterator> 
#include <algorithm> 

int main() 
{ 
    std::vector<char> v { 'a', 'b', 'c' }; 
    std::map<char, int> m; 

    std::transform(v.begin(), v.end(), std::inserter(m, m.begin()), 
     [](char c){ return std::pair<const char, int>(c, 0); }); 

    for (const auto &p : m) 
    { 
     std::cout << p.first << '\t' << p.second << std::endl; 
    } 

    return 0; 
} 

输出是

a 0 
b 0 
c 0 
1

使用boost

template<class Iterators, class Transform> 
boost::iterator_range< boost::transform_iterator< 
    typename std::decay_t<Transform>::type, 
    Iterator 
>> make_transform_range(Iterator begin, Iterator end, Transform&& t) { 
    return { 
    boost::make_transform_iterator(begin, t), 
    boost::make_transform_iterator(end, t) 
    }; 
} 

甲帮手键映射到对:

template<class T> 
struct key_to_element_t { 
    T val; 
    template<class K> 
    std::pair< typename std::decay<K>::type, T > operator()(K&& k) const { 
    return std::make_pair(std::forward<K>(k), val); 
    } 
}; 
template<class T> 
key_to_element_t< typename std::decay<T>::type > key_to_element(T&& t) { 
    return { std::forward<T>(t) }; 
} 

template<class R> 
struct range_to_container_t { 
    R r; 
    template<class C> 
    operator C()&& { 
    using std::begin; using std::end; 
    return { begin(std::forward<R>(r)), end(std::forward<R>(r)) }; 
    } 
}; 
template<class R> 
range_to_container_t<R> range_to_container(R&& r) { return std::forward<R>(r); } 

毕竟那些乱七八糟我们得到:

std::vector<char> mykeys { 'a', 'b', 'c' ]; 
std::map<char, int> myMap = range_to_container(make_transform_range(begin(mykeys), end(mykeys), key_to_element(0))); 

从在mykeys向量元素的变换的序列构建std::map直接。

很傻。

+0

好东西。 +1 – Columbo 2016-01-14 18:09:33