Re[3]: Тип переменной цикла for
От: rg45 СССР  
Дата: 23.01.19 08:37
Оценка: 1 (1) +2
Здравствуйте, sergii.p, Вы писали:

SP>а я и не шутил. Программист образца 98 года конечно ставил const & и больше не думал. Но после 11-го года программист задаёт себе извечный вопрос: а можно ли (и надо ли) мне будет перемещать элементы контейнера. Ну для меня решить этот вопрос не так то и легко. Надо сразу взвесить много факторов. И зачастую точно ответить на вопрос иногда не получается. Тогда приходит на помощь auto&&. Я так пишу и даже не останавливаюсь. Откажусь я от перемещения, или, наоборот, буду перемещать: мне уже всё равно — шапка цикла останется неизменной.


А вот здесь тебя ждет засада: переменная цикла, объявленная как auto&& в любом случае будет lvalue ссылкой (если говорить об использовании со стандарными контейнерами), несмотря на значок "&&". Она может оказаться константной ссылкой, а может оказаться неконстантной — в зависимости от константности/неконстантности самого контейнера. Но, в любом случае, это будет lvalue ссылка. Так что перемещать элементы конейнера без явного использования std::move (или развноценного преобразования) тебе все равно не удастся.

https://ideone.com/AFDBwx

#include <vector>

int main()
{
   std::vector<int> v {1, 2, 3};

   for (auto&& e : v)   
   {
         int&& rr = e; // error: cannot bind ‘int’ lvalue to ‘int&&’
   }
}


P.S. Да, за исключением единственного случая — std::vector&lt;bool&gt;
Автор: B0FEE664
Дата: 21.01.19


И даже в гипотетическом случае (какие-то нестандартные контейнеры), если эта переменная цикла каким-то образом окажется настоящей rvalue ссылкой, выражение, составленное из имени этой переменной, все равно будет являться lvalue выражением и также потребует явного преобразования для перемещения:

https://ideone.com/z6n9a7

class MyVectorInt
{
public:    
  
   struct Iterator
   {
         int operator*() const;
         void operator++();
         void operator++(int);
         bool operator == (const Iterator&) const;
         bool operator != (const Iterator&) const;
   };


   Iterator begin() const;
   Iterator end() const;
};

int main()
{
   for (auto&& e : MyVectorInt())
   {
      int&& rr = e;  // error: cannot bind ‘int’ lvalue to ‘int&&’
   }
}
--
Отредактировано 23.01.2019 9:08 rg45 . Предыдущая версия . Еще …
Отредактировано 23.01.2019 9:05 rg45 . Предыдущая версия .
Отредактировано 23.01.2019 8:57 rg45 . Предыдущая версия .
Отредактировано 23.01.2019 8:56 rg45 . Предыдущая версия .
Отредактировано 23.01.2019 8:48 rg45 . Предыдущая версия .
Отредактировано 23.01.2019 8:44 rg45 . Предыдущая версия .
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.