Сохранение строки в перегруженных скобках без изменения поля объекта

#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";
}