пятница, 16 мая 2014 г.

[prog.c++] Поосторожнее нужно с auto из C++11 :)

В C++11 появилась классная штука -- возможность автоматического вывода типа переменной при ее декларации, для чего используется ключевое слово auto вместо указания типа переменной. О полезности auto и о степени читаемости кода, в котором auto активно используется, можно спорить. Но в ряде случаев, например, когда речь идет об итераторах или о лямбда-функциях, этот механизм однозначно полезен.

Однако, как с любым полезным механизмом, с auto нужно научиться правильно обращаться и запомнить некоторые граблимоменты, которые могут привести к неожиданным открытиям. Как у меня вчера :)

В упрощенном варианте суть можно представить вот таким примером (места, на которые нужно обратить внимание, выделены):

#include <iostream>
#include <string>

class demo_t
   {
   public :
      demo_t()
         :  m_content( "Demo" )
         {}

      void
      modify()
         {
            auto s = writeable_content();
            s += " Hello, world!";
         }

      const std::string &
      content() const { return m_content; }

   private :
      std::string m_content;

      std::string &
      writeable_content() { return m_content; }
   };

int
main()
   {
      demo_t d;
      d.modify();

      std::cout << "Result: " << d.content() << std::endl;
   }

Как вы думаете, после модификации переменной s в методе demo_t::modify(), какое значение окажется в demo_t::m_content, если метод writeable_content() возвращает ссылку на m_content?

Так вот, правильный ответ: значение demo_t::m_content не изменится. Т.к. в методе modify() будет происходить изменение не m_content, а локальной переменной типа std::string.

Для того, чтобы s имел тип std::string& нужно декларировать s вот так: auto & s = writeable_content().

Комментариев нет: