경고 : 이것은 입니다. 거친 모형을 원하는 동작으로 처리했습니다. 이것은 좋은 코드에 가깝지는 않지만 빠른 속도이며이를 수행하는 기술을 보여 주어야합니다.
자신의 롤링을 고려하기 전에 Boost의 multi_index
과 같은 기존 솔루션을 사용해야합니다. 더 쉽고, 빠르며, 오류가 발생하기 쉽고, 더 잘 설계 될 것입니다.
template<typename Key, typename Val>
class OrderedMap
{
private:
std::vector<std::pair<Key, Val>> ordered;
std::map<Key, std::size_t> lookup;
public:
void insert(Key k, Val v)
{
ordered.push_back(std::pair<Key, Val>(k, v));
lookup.emplace(k, ordered.size() - 1);
}
Val find(Key k)
{
std::size_t index = lookup[k];
return ordered[index].second;
}
// "typename" needed as the "iterator" is a dependent type
typename std::vector<std::pair<Key, Val>>::iterator begin()
{
return ordered.begin();
}
typename std::vector<std::pair<Key, Val>>::iterator end()
{
return ordered.end();
}
};
우리가 필요한 것은 삽입 된 요소의 실제 순서를 추적하는 std::vector<std::pair<Key, Val>>
이며, std::map<Key, std::size_t>
키와 값 인덱스 간의 연관성을 추적하도록. 그런 다음이 클래스에서 원하는 기능을 이러한 내부 백업/조회 구조의 기능에 위임 할 수 있습니다.
이 클래스가 원하는 동작과 내부 컨테이너 사이에서 제공하는 인터페이스는 사용자가 원하는대로 견고 할 수 있습니다. 여기서는 데모에 필요한 못생긴 뼈만 잡아 먹었습니다.
See a quick demo here.
OrderedMap<std::string, int> m;
m.insert("1", 1);
m.insert("2", 2);
m.insert("3", 3);
std::cout << m.find("2") << std::endl << std::endl;
for (auto i = m.begin(); i != m.end(); i++)
std::cout << i->first << " " << i->second << std::endl;
std::cout << std::endl;
출력 나타냅니다 :
물론
2
1 1
2 2
3 3
는 언어 가능성이 - 당신이 삽입 된 항목과 뒷면'벡터'와 키 조회에 대한 '지도 을'사용하여 시도가을/제거 삽입 순서로? –
hnefatl
@KillzoneKid 놀랍게도하지 않습니다! 이것이 제가 처음으로 가졌던 가장 잘못된 해결책이었습니다. – JosephJerrel
당신은 boost :: multi_index를 보았습니까? 나는 네가하는 일을 할 수 있는지 잘 모르겠다. – SoronelHaetir