STL 문자열에서 작동하는 조인 함수가 있습니다. 나는이 같은 컨테이너에 적용 할 수 있도록하려면 :C++ STL 연관 컨테이너의 키/값 결합
getFoos(const std::multimap<std::string, std::string>& map) {
return join_values(",", map.equal_range("foo"));
즉, 컬렉션에 일치하는 모든 키를 찾아 주어진 분리 된 단일 문자열로 값을 연결.
template <typename T>
struct join_range_values : public T::const_iterator::value_type::second_type {
typedef typename T::const_iterator::value_type pair_type;
typedef typename pair_type::second_type value_type;
join_range_values(const value_type& sep) : sep(sep) { }
void operator()(const pair_type& p) {
// this function is actually more complex...
*this += sep;
*this += p.second;
}
private:
const value_type sep;
};
template <typename T>
typename T::const_iterator::value_type::second_type join_values(
const typename T::const_iterator::value_type::second_type& sep,
const std::pair<typename T::const_iterator, typename T::const_iterator>& range) {
return std::for_each(range.first, range.second, join_range_values<T>(sep));
}
(나는 것을 깨닫게 :
lower_bound()
와 키의 범위
upper_bound()
, 컨테이너의 전체 내용에 대한
begin()
/
end()
등과 같은 일이 ..
내가 얻을 수있는 가장 가까운는 다음과 std::string
에서 상속하거나 키/값 유형이 무엇이든 일반적으로 나쁜 생각으로 간주되지만 오버로드 나 오버라이드 기능이 아니며 가상 소멸자가 필요하지 않습니다. 암시 적 변환 연산자를 정의 할 필요없이 for_each
의 결과를 사용하십시오.
second_type
및 p.second
대신 first_type
및 p.first
을 사용하는 매우 유사한 정의가 join_range_keys
입니다. 나는 비슷한 정의가 std::set
과 std::multiset
키를 합치기 위해 작동한다고 가정하고 있지만, 그것에 대한 필요성은 전혀 없습니다.
다양한 유형의 문자열이있는 컨테이너에이 기능을 적용 할 수 있습니다.
typedef std::multimap<std::string, std::string> NNMap;
const NNMap col;
const std::string a = join_keys<NNMap>(",", col.equal_range("foo"));
const std::string b = join_values<NNMap>(",", col.equal_range("foo"));
typedef std::multimap<std::string, std::wstring> NWMap;
const NWMap wcol;
const std::string c = join_keys<NWMap>(",", wcol.equal_range("foo"));
const std::wstring d = join_values<NWMap>(L",", wcol.equal_range("foo"));
typedef std::multimap<std::wstring, std::wstring> WWMap;
const WWMap wwcol;
const std::wstring e = join_keys<WWMap>(L",", wwcol.equal_range(L"foo"));
const std::wstring f = join_values<WWMap>(L",", wwcol.equal_range(L"foo"));
이 몇 가지 질문을 나에게 잎 :
- 내가 몇 가지 쉬운 방법 실종 키와 값 유형
string
및wstring
의 조합으로map
및multimap
의 조합이 작동하는 것 같다 똑같은 일을 완수합니까? 함수 서명은 특히 지나치게 복잡해 보입니다. join_values
은 매번join_values<MapType>
을 호출 할 필요가 없도록 템플릿 매개 변수 유형을 자동으로 추론 할 수 있습니까?join_values
및join_keys
기능과 펑터를 리팩터링하여 대부분의 코드가 중복되지 않도록하려면 어떻게해야합니까?
나는 std::accumulate
에 따라 약간 간단한 해결책을 찾았어요,하지만 범위의 각 요소에 대한 전체 문자열의 두 전체 복사 작업을 필요로하는 것, 그래서 지금까지 내가 말할 수있는, 훨씬 효율적입니다.
template <typename T>
struct join_value_range_accum : public T::const_iterator::value_type::second_type
{
typedef typename T::const_iterator::value_type::second_type value_type;
join_value_range_accum(const value_type& sep) : sep(sep) {}
using value_type::operator=;
value_type operator+(const typename T::const_iterator::value_type& p)
{
return *this + sep + p.second;
}
private:
const value_type sep;
};
typedef std::multimap<std::string, std::string> Map;
Map::_Pairii range = map.equal_range("foo");
std::accumulate(range.first, range.second, join_value_range_accum<Map>(","));
오, 소년, 나는 이것을 먼저 소화해야합니다 ... 잠깐 만요! –