2009-02-05 3 views
1

У меня есть карта, определенная как этотПочему я не могу поставить итератор на карту?

std::map<some_key_type, std::string::iterator> mIteratorMap; 

и огромная строка с именем «mHugeString». Тогда я иду корыто строки сбора итераторов, как это:

std::string::iterator It=mHugeString.begin(); 
std::string::iterator EndIt=mHugeString.end(); 
for(;It!=EndIt;++It){ 
    ...defining a key element... 
    if(need_to_store_an_iterator)mIteratorMap[key_of_a_right_type]=It; 
} 

В конце концов, я должен делат карты, где итератор, связанная с каким-то ключом. Но итератор как-то теряет себя при соединении с ключом «make_pair», если только он не указывает на место где-то в конце строки. Трудно сказать, но, может быть, последние 256 байтов в порядке.

Итак, вопрос заключается не в том, как избежать потери итераторов, но это была глупая идея хранить их в любом случае, но почему попытка сохранить итератор в начале строки терпит неудачу и почему то же самое с итераторами на конце работает отлично? В чем разница между ними?

+0

Как хранить итератор? Это 'mIteratorMap.insert (Map :: value_type (key_of_a_right_type, It));' или 'mIteratorMap [key_of_a_right_type] = It;'? – jfs

+0

Можете ли вы обновить свой псевдокод, чтобы уточнить, как вы вставляете карту? Это делает его похожим на то, что вы создаете временный, но это недействительный вызов ctor: if (need_to_store_an_iterator) mIteratorMap (key_of_a_right_type, It); –

+0

Плохо, исправлено. Но вставка работает сэкономить. Даже просто попытка сделать пару не удалась. – akalenuk

ответ

3

Я не пробовал, но я бы ожидал, что вы, конечно, можете хранить значения итератора в качестве значений на карте.

Знаете ли вы, что если вы измените содержимое mHugeString, то все итераторы, которые вы ранее сохранили, теперь недействительны?

Возможно, вы захотите сохранить индекс в строке вместо итератора.

+0

Да, и я ожидал того же. Похоже, что что-то не так с реализацией «make_pair». – akalenuk

3

Я не уверен, почему это должно быть проблемой. Я написал этот код, чтобы проверить хранение и извлечение итератора, который, кажется, работает нормально.

#include <string> 
#include <iostream> 
#include <map> 

enum UniqueKey {One, Two, Three}; 

typedef std::map<UniqueKey, std::string::iterator> UniqueKeyStringMap; 

int main() 
{ 
    UniqueKeyStringMap storage; 

    std::string stringOne = "This is one string"; 

    std::string::iterator it = stringOne.begin() + 8; // "o" 
    std::cout << " Iterator to store: " << std::string(it, it + 3) << std::endl; 

    storage[UniqueKey::One] = it; // Store iterator 

    // Retrieve and print, string and map are valid 

    UniqueKeyStringMap::iterator mapIter = storage.find(UniqueKey::One); 
    if (mapIter != storage.end()) 
    { 
     std::cout << " From storage: " << 
      std::string(mapIter->second, mapIter->second + 3) << std::endl; 
    } 
} 

ожидается выход: [Примечание Я не использую make_pair, как это не должно быть уместно, дать попробовать, не используя его, хотя!]: Итератор для хранения: один С хранения: один

+0

У меня тоже нет проблем с небольшой строкой. Проблема возникает при попытке сохранить итератор далеко от конца строки. – akalenuk

+0

Что вы подразумеваете под «далеко от конца»? Используете ли вы обратный итератор? Итераторы в основном ptrs, поэтому не должны иметь никаких ограничений. Вы уверены, что не развращаете свое хранилище или что-то еще? Насколько велики ваши строки? – Ketan

1

Это нормально , вы можете хранить итераторы на карте. Если вы получите некоторую ошибку, это вызвано чем-то другим. Обратите внимание: если вы измените свою строку, итераторы, указывающие на вашу строку, станут недействительными.

Пожалуйста, покажите нам полный, компилируемый фрагмент кода, который оказывается непригодным для использования, поэтому мы можем его проанализировать.