是否有将多个集合包含在多映射中的优雅可能性



我有几个相同类型的集合:

std::set< TDate> spieltagDatum;

我想把它们都包括在这种类型的多映射中:

std::multimap<TDate, int> ereignis;

是否有一种优雅的可能性(也许是与lambda相关的函数?(将ONE集的所有成员都包含在上面的多映射中,而不使用迭代器机制?(在插入过程中,多映射对应使用INT参数进行富集(。

我可以建议使用简化的for循环来代替迭代器,auto如下。

例如,我使用了整数TDate,在我的代码中也可以使用任何函数来填充multimap的值,而不是123

在线试用!

#include <map>
#include <set>
int main() {
using TDate = int;
std::set<TDate> spieltagDatum = {3, 5, 7};
std::multimap<TDate, int> ereignis;
for (auto & e: spieltagDatum)
ereignis.emplace(e, 123);
}

你说的"不使用迭代器机制";?(不要使用迭代器,风险自负(

正如您所描述的,您所做的是1(转换(通过丰富(和2(插入,因此答案是std::tranform + std::insert

#include <algorithm> // transform
#include <cassert>
#include <map>
#include <set>
int main() {
using TDate = int;
std::set<TDate> spieltagDatum = {3, 5, 7};
std::set<TDate> ...;
std::multimap<TDate, int> ereignis;
auto enrich = [](auto e){return std::make_pair(e, 123);};
std::transform(
begin(spieltagDatum), end(spieltagDatum), 
std::inserter(ereignis, end(ereignis)),
enrich
);
... // repeat for other sets if necessary
assert( ereignis.find(5) != ereignis.end() );
assert( ereignis.find(5)->second == 123 );
}

https://godbolt.org/z/zzYbKK83d


使用库的一个更具声明性的选项,基于@prephistoricpenguin的答案是:(IMO它主要在C++17中是有价值的,其中许多模板参数并不是真正必要的(

#include <cassert>
#include <map>
#include <set>
#include <boost/iterator/transform_iterator.hpp>
int main() {
using TDate = int;
std::set<TDate> spieltagDatum = {3, 5, 7};

auto enriched = [](auto it){
return boost::transform_iterator(it, [](auto e){return std::pair(e, 123);});
};
std::multimap ereignis(
enriched(begin(spieltagDatum)),
enriched(end  (spieltagDatum))
);
assert( ereignis.find(5) != ereignis.end() );
assert( ereignis.find(5)->second == 123 );
}

https://godbolt.org/z/6ajssjjjP

一个可能的答案是编写一个转换迭代器类,然后使用迭代器来构造multimap实例。
#include <iostream>
#include <iterator>
#include <map>
#include <set>
template <typename KeyT, typename ValT>
class ConvertIter
: public std::iterator<std::forward_iterator_tag, std::pair<KeyT, ValT>> {
using SetIter = typename std::set<KeyT>::iterator;
public:
ConvertIter(SetIter itr, ValT v = ValT{}) : _itr(itr), _val(v) {}
bool operator==(const ConvertIter& other) { return other._itr == _itr; }
bool operator!=(const ConvertIter& other) { return other._itr != _itr; }
std::pair<KeyT, ValT> operator*() const {
return {*_itr, _val};
}
ConvertIter& operator++() {
++_itr;
return *this;
}
ConvertIter& operator++(int) {
++_itr;
return *this;
}
private:
SetIter _itr;
ValT _val;
};
int main() {
using TDate = int;
std::set<TDate> spieltagDatum = {3, 5, 7};
std::multimap<TDate, int> ereignis(
ConvertIter<TDate, int>(spieltagDatum.begin(), 123),
ConvertIter<TDate, int>(spieltagDatum.end()));
for (auto [date, val] : ereignis) {
std::cout << "[" << date << "," << val << "]" << std::endl;
}
return 0;
}

演示:https://godbolt.org/z/cr98f15jq

最新更新