с++0x rvalue reference и возврат по значению

Тема в разделе "LANGS.C", создана пользователем Velheart, 23 янв 2012.

  1. Velheart

    Velheart New Member

    Публикаций:
    0
    Регистрация:
    2 июн 2008
    Сообщения:
    526
    Привет, предположим есть код:

    Код (Text):
    1. std::vector<int> Fun()
    2. {
    3.     std::vector<int> res;
    4.     // some initializations
    5.     // return res;
    6.     return std::move(res);
    7. }
    8.  
    9.  std::vector<int> res = Fun();
    Вот я даже в дебаге не заметил разницы между return res и return std::move(res), по идее же должно быть одно копирование без std::move, или я чего-то туплю? Т.е. это оптимизация компилятора, или я в стандарте чето не так понимаю\помню?
     
  2. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    Полагаю это nrvo - http://msdn.microsoft.com/en-us/library/ms364057%28v=vs.80%29.aspx
     
  3. Velheart

    Velheart New Member

    Публикаций:
    0
    Регистрация:
    2 июн 2008
    Сообщения:
    526
    Я про эту штуку знаю, просто думал, что в дебаге не должно ее быть..
     
  4. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    С другой стороны я не понимаю почему здесь должно быть различие.

    return std::move(res);
    return std::vector<int> res;

    Разве тут есть что-то, что должно приводить к различию?
     
  5. _DEN_

    _DEN_ DEN

    Публикаций:
    0
    Регистрация:
    8 окт 2003
    Сообщения:
    5.383
    Адрес:
    Йобастан
    Booster
    Есть. Со вторым случаем все понятно - вызывается конструктор копирования.

    Первый случай. Посмотрим на std::move:

    Код (Text):
    1. template<typename T>
    2. remove_reference<T>::type&& move(T&& a)
    3. {
    4.       return a;
    5. }
    std::move превращает ссылку на объект в &&, что при return дает вызов не копирующего, а move-конструктора.
     
  6. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    std::move возвращает ссылку на rvalue, но не Fun().
     
  7. Velheart

    Velheart New Member

    Публикаций:
    0
    Регистрация:
    2 июн 2008
    Сообщения:
    526
    Да, но у вектора есть мув-конструктор, поэтому в темповый объект который будет возвращен, вектор будет мувнут, а не скопирован, а этот темповый, соответственно мувнут в результирующий, потому как он рвэлью, так вот я думаю, стоит ли по-хорошему писать мув перед возвратом везде, или это 100% не нужно.
     
  8. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    А да, темповый тоже должен получить rvalue reference и вся цепочка объектов пойдёт с move конструкторами, только на количество временных объектов это вряд ли повлияет. Если действительно идут одни вызовы move конструкторов, тогда nrvo тут не причём, видимо компилятор шибко умный.