C ++: ссылки на параметры - PullRequest
       11

C ++: ссылки на параметры

3 голосов
/ 29 февраля 2012

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

Следуя этой логике, разве в следующем коде нет аналогичной проблемы?

#include <iostream>

class T
{
  public:
    T& operator+=(const T& t) { this->x += t.x; return *this; }
    T(int x) : x(x) {}
    int x;
    ~T() 
    { 
      std::cout << "My value is " << this->x << " and I'm dead." << std::endl; 
      this->x = -999;
    }
};

int main() 
{
  const T& t = (T(2) += T(3));
  std::cout << t.x << std::endl;
}

И если да, то как мне написать оператор +=, чтобы избежать этой проблемы?

Я также предполагаю, что будут проблемы со следующим кодом в C ++ 11, но я не проверял его:

#include <iostream>
#include <string>

int main()
{
  for ( char x : std::string("hello") += std::string("world") )
  {
    std::cout << x << std::endl;
  }
}

Казалось бы, в результате вы никогда не должны возвращать ссылки на параметры функции, если только вы не готовы рисковать неопределенным поведением в диапазоне, основанном на циклах.

1 Ответ

1 голос
/ 29 февраля 2012

Для таких случаев возвращение ссылки на *this является ожидаемым поведением (это делается для включения Метод цепочки ).Так как this не является локальной переменной функции, она не выйдет за пределы области видимости.

Что касается второй части вашего вопроса, в вашем случае диапазон, основанный на цикле for, определяется как эквивалентныйthis (§ 6.5.4 [stmt.ranged]):

{
    auto && __range = std::string("hello") += std::string("world");
    for ( auto __begin = begin(__range),
               __end = end(__range);
          __begin != __end;
          ++__begin ) {
        char x = *__begin;
        std::cout << x << std::endl;
    }
}

Как видите, перебираемая вами строка захватывается с помощью auto &&, который может связать константную ссылку, возвращаемую +=.

Редактировать Как Мартиньо указывает в своем комментарии, += возвращает неконстантную ссылку, поэтому показанный код имеет неопределенное поведение.

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