#c #reference #overloading #variable-assignment #brackets
#c #ссылка #перегрузка #переменная-назначение #скобки
Вопрос:
У меня есть проблема в моем коде, которую я не могу понять. Я хочу составить список списков и использовать его как двумерный ассоциативный массив.
Что-то вроде этого:
token["window"]["title"] = "Amazing!";
cout << token["window"]["title"]; //Amazing!
Вторая линия работает хорошо. Данные считываются из файла. Проблема связана с первой инструкцией.
Вот как я перегружаю вторые квадратные тормоза:
TokenPair Token::operator[](string keyName){
for( list<TokenPair>::iterator pair=keys.begin(); pair != keys.end(); pair){
if(pair->key == keyName){
return *pair;
}
}
}
Как вы видите, я возвращаю объект класса TokenPair. Чтобы правильно получить значение из object (field TokenPair::value), я перегружаю потоковую передачу и приведение к string().
TokenPair::operator string() const{
return value;
}
ostream amp; operator<< (ostream amp;stream, const TokenPair amp;pair){
return stream << pair.value;
}
И, как я уже говорил, получение ценности работает отлично. Проблема заключается в перегрузке оператора атрибуции:
TokenPair TokenPair::operator=( const string newValue ){
value = newValue;
return *this;
}
Этот метод определяет значение, но он не помнит этого! Например:
token["window"]["title"] = "Ok";
приведет к тому, что внутри метода TokenPair::operator= variable newValue==»Ok» и после первой строки четное значение устанавливается в «Ok»; Но когда я позже сделаю:
cout << token["window"]["title"] ;
поле в TokenPair по-прежнему не изменено. Я хочу спросить: почему? Может быть, итераторы возвращают копию этого объекта? Я не знаю. Пожалуйста, помогите.
Комментарии:
1. почему бы не
map
map
использовать s и просто использовать готовый контейнер STL, который делает именно то, что вы хотите?2. Может быть, потому, что я никогда не слышал об этом: c Могу ли я создать двухмерную карту? Карта карт? Если да, это означает, что я теряю два дня в своей жизни.
3. конечно, вы можете, в этом весь смысл.
Ответ №1:
Ваша проблема в том, что operator[]
возвращает TokenPair
значение by , поэтому при назначении вы присваиваете новое значение временному, а не объекту, хранящемуся в списке.
Чтобы это сработало operator[]
, необходимо вернуть ссылку на объект, который вы хотите изменить.
Комментарии:
1. ДА. Вы правы. Я знал, что это что-то с плохим возвратом, но я не могу понять, что звездочка после инструкции возврата недостаточна для возврата ссылки. После добавления амперсанта в объявление все работает так, как мне нужно. Спасибо за помощь 🙂 Для будущих читателей: мне нужно было добавить аперсант в оба operator[] . Не только для вторых скобок, но и для первых!
2. См. FAQ по C
about operator[]
: parashift.com/c -faq-lite/operator-overloading.html#faq-13.10
Ответ №2:
Вот пример того, как использовать map-of-maps:
#include <map>
#include <string>
#include <iostream>
#include <sstream>
const char inputString[] =
"President 16 Lincoln "
"President 1 Washington "
"State Best Illinois "
"State Biggest Alaska ";
int main () {
std::map<std::string, std::map<std::string, std::string> > token;
std::string primary, secondary, resu<
std::istringstream input(inputString);
while( input >> primary >> secondary >> result )
token[primary][secondary] = resu<
std::cout << "Abe " << token["President"]["16"] << "n";
std::cout << "Springfield, " << token["State"]["Best"] << "n";
std::cout << "Blank: " << token["President"]["43"] << "n";
}