Проблема при реализации итератора, подобного карте, в C ++ - PullRequest
1 голос
/ 16 ноября 2010

Я только что завершил реализацию общего списка пропусков в C ++ и хочу привести его к STL-подобному итератору.Проблема возникает при перегрузке оператора «->»: требуется вернуть ссылку на iterator :: value_type, в моем случае это std :: pair, где K - тип ключа, а V - тип значения моей карты.контейнерКод следующий:

value_type& operator->() { return value_type(inner->key, inner->value); }

Компилятор возвращает мне несколько сообщений ненависти о ссылках на временные объекты, и я с ним полностью согласен;у меня вопрос: как, черт возьми, я должен сделать, чтобы вернуть ссылку на пару, не помещая член пары в мой класс итератора?

Ответы [ 4 ]

2 голосов
/ 16 ноября 2010
value_type& operator->() { return value_type(inner->key, inner->value); }

Ваш тип возвращаемого значения является ссылкой на value_type, но вы возвращаете локально созданный экземпляр, который будет уничтожен в конце области действия функции / оператора (т. Е. Закрывающего }.) ссылка на мусор, поэтому ваш компилятор ненавидит вас.

Если вместо этого вы вернете по значению , у вас будет правильный и функциональный код. (Независимо от того, хотите ли вы вернуть по значению, зависит от типа value_type.)

value_type operator->() { return value_type(inner->key, inner->value); }

Еще лучше было бы сохранить одно value_type в качестве поля члена вашего класса, но вы говорите, что не хотите, так что это единственный другой реалистичный вариант.

2 голосов
/ 16 ноября 2010

С одной стороны, operator-> должен возвращать указатель или что-то, что имеет собственный метод operator->().Но если у вас нет value_type, то есть pair<const K,V>, вы не можете легко вернуть указатель на него.

Можете ли вы изменить определение inner, чтобы оноесть или содержит pair?Вы можете добавить аксессоры, такие как key() и value(), чтобы избежать путаницы first и second в большинстве мест.

Или, в зависимости от того, как std::map вам нужно это действовать,возможно, вам следует использовать другой value_type typedef, который описывает то, что у вас действительно есть.

0 голосов
/ 16 ноября 2010

operator -> () должен возвращать только те значения, которые являются указателями или имеют перегруженные функции operator -> (), определенные для них.Смысл этой функции не в том, чтобы выполнить саму операцию «->», а в том, чтобы предоставить объект или указатель, для которого будет работать оператор «->».

В вашем случае для этого вам необходимо вернуть указатель на пару.Если вы действительно хотели бы избежать сохранения пары внутри вашего класса, вы могли бы заставить функцию возвращать умный указатель на недавно выделенную пару, чтобы не происходило утечек памяти во время операции.

0 голосов
/ 16 ноября 2010

То, что вы делаете в своем фрагменте, - это создание нового экземпляра value_type. Этот объект, конечно, будет удален после того, как оператор функции / метода -> () останется, что оставит вашу ссылку, которую вы только что вернули, указывая на никуда.

Что вам нужно сделать, это вернуть ссылку на соответствующий элемент уже в вашем списке.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...