Re: initializer_list - убийца move семантики
От: uzhas Ниоткуда  
Дата: 25.10.18 10:41
Оценка: :)
Здравствуйте, rg45, Вы писали:

R>Будьте осмотрительны


желтенько
не смог пройти мимо
Re[6]: initializer_list - убийца move семантики
От: B0FEE664  
Дата: 25.10.18 11:58
Оценка:
Здравствуйте, rg45, Вы писали:

R>Зачем же ты move прямо внутрь запихнул? move ведь не всегда должно быть, а только когда нужно:

Исходил из того, что у MovableNonCopyable не может быть копий. Согласен на std::forward<T>(t).
И каждый день — без права на ошибку...
Re[6]: initializer_list - убийца move семантики
От: N. I.  
Дата: 25.10.18 14:12
Оценка: 11 (2)
rg45:

R>move ведь не всегда должно быть, а только когда нужно:

R>https://ideone.com/VL1Kci

При желании количество перемещений можно ещё сократить:
https://wandbox.org/permlink/5GPsTQXVnTI1hwYT
Re[6]: initializer_list - убийца move семантики
От: B0FEE664  
Дата: 30.10.18 14:57
Оценка: +1
Здравствуйте, andyp, Вы писали:

R>>Так просто ведь все — aggregate initialization — это старая добрая си-шная инициализация массивов и структур. А list initialization — уродец, основанный на initializer_list-ах, придуманный каким-то студентом, для которого шашечки важнее, чем ехать.


A>Это если только на эти две смотреть. А так там еще default, zero, value, direct, constant... Тьма их. В общем, ты толкнул меня на 801 круг


Главное помнить, что:
std::vector<int> v2(1, 2); — это один элемент со значением 2
std::vector<int> v1{1, 2}; — это два элемента со значениями 1 и 2
И каждый день — без права на ошибку...
Re: initializer_list - убийца move семантики
От: Анатолий Широков СССР  
Дата: 30.10.18 15:25
Оценка:
Здравствуйте, rg45, Вы писали:

R>Будьте осмотрительны, используя initializer_list для инициализации. Помните, его элементы всегда копируются, а не перемещаются, даже когда вы наполняете его rvalue значениями:


#include <iostream>
#include <initializer_list>

struct MovableNonCopyable
{
  MovableNonCopyable() {
    std::cout << "1" << std::endl;
  }
  MovableNonCopyable(MovableNonCopyable&&) {
    std::cout << "2" << std::endl;
  }
  MovableNonCopyable& operator=(MovableNonCopyable&&) = default;
  MovableNonCopyable(MovableNonCopyable const &) = delete;
  MovableNonCopyable& operator=(MovableNonCopyable const &) = delete;
};

struct MovableNonCopyableConsumer {
  MovableNonCopyableConsumer(std::initializer_list<MovableNonCopyable> lst) {
    for(const MovableNonCopyable& i : lst) {
    }
  }
};


int main() {
  MovableNonCopyableConsumer v { MovableNonCopyable(), MovableNonCopyable(), MovableNonCopyable() };
}


вывод:

1
1
1

Re[2]: initializer_list - убийца move семантики
От: B0FEE664  
Дата: 30.10.18 15:54
Оценка:
Здравствуйте, Анатолий Широков, Вы писали:

R>>Будьте осмотрительны, используя initializer_list для инициализации. Помните, его элементы всегда копируются, а не перемещаются, даже когда вы наполняете его rvalue значениями:


АШ>вывод:

Всё это очень интересно, но жаль, что перемещение элементов из списка вам так и не удалось продемонстрировать.
И каждый день — без права на ошибку...
Re[7]: initializer_list - убийца move семантики
От: andyp  
Дата: 30.10.18 17:52
Оценка: 1 (1) :)
Здравствуйте, B0FEE664, Вы писали:

BFE>Главное помнить, что:

BFE>std::vector<int> v2(1, 2); — это один элемент со значением 2
BFE>std::vector<int> v1{1, 2}; — это два элемента со значениями 1 и 2

Угу, что Карл Маркс и Фридрих Энгельс — два человека, а не четыре, Слава КПСС — вообще не человек, а
auto c = {1,2,3,4};

есть std::initializer_list<int>
Re[3]: initializer_list - убийца move семантики
От: Jack128  
Дата: 16.11.18 07:31
Оценка: +1
Здравствуйте, B0FEE664, Вы писали:

BFE>Здравствуйте, Анатолий Широков, Вы писали:


R>>>Будьте осмотрительны, используя initializer_list для инициализации. Помните, его элементы всегда копируются, а не перемещаются, даже когда вы наполняете его rvalue значениями:


АШ>>вывод:

BFE>Всё это очень интересно, но жаль, что перемещение элементов из списка вам так и не удалось продемонстрировать.

const_cast и вперёд.

template <class T>
std::vector<T> make_vector(std::initializer_list<T> lst) {
    std::vector<T> result;
    result.reserve(lst.size());
    for(const T& item: lst) {
        T& item2 = const_cast<T&>(item);
        result.emplace_back(std::move(item2));
    }
    return result;
}


Вообще проблема не в initializer_list как каком то специальном типе, а в том, что его итераторы возвращают указатели на _константные_ элементы. а их перемещать нельзя.
Re[7]: initializer_list - убийца move семантики
От: Skorodum Россия  
Дата: 16.11.18 08:44
Оценка:
Здравствуйте, B0FEE664, Вы писали:

BFE>Главное помнить, что:

BFE>std::vector<int> v2(1, 2); — это один элемент со значением 2
BFE>std::vector<int> v1{1, 2}; — это два элемента со значениями 1 и 2

Недавно наступил на эти грабли... (смешанные чувства)
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.