В картах STL лучше использовать map :: insert, чем []? - PullRequest
197 голосов
/ 28 ноября 2008

Некоторое время назад у меня была дискуссия с коллегой о том, как вставить значения в STL map . Я предпочел map[key] = value; потому что это естественно и понятно для чтения, тогда как он предпочитал map.insert(std::make_pair(key, value))

Я только что спросил его, и никто из нас не может вспомнить причину, по которой вставка лучше, но я уверен, что это был не просто стиль, а техническая причина, например, эффективность. Ссылка SGI STL просто говорит: «Строго говоря, эта функция-член не нужна: она существует только для удобства».

Кто-нибудь может сказать мне эту причину, или я просто мечтаю, что она есть?

Ответы [ 12 ]

1 голос
/ 18 марта 2013

Вот еще один пример, показывающий, что operator[] перезаписывает значение ключа, если оно существует, но .insert не перезаписывает значение, если оно существует.

void mapTest()
{
  map<int,float> m;


  for( int i = 0 ; i  <=  2 ; i++ )
  {
    pair<map<int,float>::iterator,bool> result = m.insert( make_pair( 5, (float)i ) ) ;

    if( result.second )
      printf( "%d=>value %f successfully inserted as brand new value\n", result.first->first, result.first->second ) ;
    else
      printf( "! The map already contained %d=>value %f, nothing changed\n", result.first->first, result.first->second ) ;
  }

  puts( "All map values:" ) ;
  for( map<int,float>::iterator iter = m.begin() ; iter !=m.end() ; ++iter )
    printf( "%d=>%f\n", iter->first, iter->second ) ;

  /// now watch this.. 
  m[5]=900.f ; //using operator[] OVERWRITES map values
  puts( "All map values:" ) ;
  for( map<int,float>::iterator iter = m.begin() ; iter !=m.end() ; ++iter )
    printf( "%d=>%f\n", iter->first, iter->second ) ;

}
1 голос
/ 26 декабря 2012

Это довольно ограниченный случай, но, судя по полученным мною комментариям, стоит отметить.

Я видел, как люди в прошлом использовали карты в виде

map< const key, const val> Map;

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

const_cast< T >Map[]=val;

Их причина сделать это, насколько я помню, заключалась в том, что они были уверены, что в этих определенных фрагментах кода они не будут перезаписывать значения карты; следовательно, продолжим работу с более «читаемым» методом [].

У меня никогда не было прямых проблем с кодом, написанным этими людьми, но до сегодняшнего дня я твердо убежден, что риски - пусть даже небольшие - не следует принимать, когда их легко избежать.

В тех случаях, когда вы имеете дело со значениями карты, которые абсолютно не должны быть перезаписаны , используйте insert. Не делайте исключений просто для удобства чтения.

...