Re: как эффективно передать элементы из одного вектора в другой
От: watchmaker  
Дата: 07.04.16 16:15
Оценка: 3 (2)
Здравствуйте, sci_reseacher, Вы писали:

_>Как наиболее эффективно (правильно) выполнить передачу (копирование, перемещение ... ) значений из одного вектора x (внутри объекта некоторого класса) в другой вектор y или z, который находиться вне класса в С++11?


Для перемещения — просто и без затей:
std::vector<int> z = std::move(a.x);

Для копирования есть два варианта. Если вектор, в который происходит копирование, уже существует, обладает ненулевым capacity и есть желание эту ёмкость переиспользовать, то можно делать
z.assign(a.x.begin(), a.x.end());

Во всех остальных случаях — просто копируй:
std::vector<int> z = a.x;

Как это всё будет в функции завёрнуто, есть член x хочется сделать недоступным извне класса, — по большом счёту не так уж и важно.
Можно простую обёртку сделать
std::vector<int>&& A::ConsumeX() {
  return std::move(x);
}

Или через ref-qulifiers отдать выбор нужной перегрузки компилятору:
using V = std::vector<int>;

  const V& CopyX() const& {
    return x;
  }
  
  V&& CopyX() && {
    return std::move(x);
  }
  
  void CopyTo(V& target) const& {
    target.assign(x.begin(), x.end());
  }
  
  void CopyTo(V& target) && {
    target.swap(x);
  }

Тогда, например, получится

V data1;
data1.reserve(1000);

A a;
a.CopyTo(data1); // переиспользование выделенного буфера в data1

V data2 = A().CopyX(); // на самом деле не копирование, а перемещение из x
V data3 = a.CopyX(); // а тут честное копирование
Re[3]: как эффективно передать элементы из одного вектора в другой
От: watchmaker  
Дата: 08.04.16 10:17
Оценка: 2 (1)
Здравствуйте, sci_reseacher, Вы писали:

_>требуется только читать эти данные вне (править нельзя).

_>Вот так будет верно?

Да. Если данные требуется только читать, то, конечно, ни копировать, ни перемещать их не нужно. В этой ситуации использовать константную ссылку на них — прямо лучший вариант.
Re[3]: как эффективно передать элементы из одного вектора в другой
От: _hum_ Беларусь  
Дата: 08.04.16 10:41
Оценка: 2 (1)
Здравствуйте, sci_reseacher, Вы писали:

_>Есть внутренний вектор с данными (правят их методы класса),


_>требуется только читать эти данные вне (править нельзя).


_>Вот так будет верно?


_>
_>class A {
_>std::vector<int> x; // данные здесь
_>public:
_>A(const size_t n){ x.resize(n,25); }
_>const std::vector<int> & getRefToV(){ return x; }
_>};

_>int main(){
_>    A a(5);
_>    const std::vector<int> & ref_to_x = a.getRefToV(); // здесь просто ссылка
_>    for( const auto & e: ref_to_x) { std::cout << e << ' ' ; }
_>}
_>$ c++ -std=c++11 t2.cpp -o t2 && ./t2
_>25 25 25 25 25 
_>


только тогда уже

const std::vector<int> & getConstRefToV(){ return x; }

а вообще, как, ан мой взгляд, правильно выше отметил Егор, ваше дело отдать доступ к объекту,а уже на стороне принимающего должны решать, скопировать его "чтобы гарантировать целостность во времени" или пренебречь (если это не приницпиально). потому, имхо, не надо в названии указывать "RefToV"
Re: как эффективно передать элементы из одного вектора в другой
От: push  
Дата: 07.04.16 15:30
Оценка: 1 (1)
Хм, вроде же очевидно, что если надо скопировать — то через std::copy, если переместить — то через перемещение. Всё зависит от того, что именно надо.
Если без разницы — то скорее всего передавать ничего не нужно, а нужен доступ к части значений. В этом случае эффективней ограничится просто передачей индексов/итераторов.
Re: как эффективно передать элементы из одного вектора в другой
От: __kot2  
Дата: 07.04.16 17:41
Оценка: 1 (1)
Здравствуйте, sci_reseacher, Вы писали:
_>Как наиболее эффективно (правильно) выполнить передачу (копирование, перемещение ... ) значений из одного вектора x (внутри объекта некоторого класса) в другой вектор y или z, который находиться вне класса в С++11?
перемещение —
по-старинке — a.swap(b), по-новому — a = std::move(b)
Re[6]: как эффективно передать элементы из одного вектора в другой
От: _hum_ Беларусь  
Дата: 07.04.16 20:50
Оценка: -1
Здравствуйте, T4r4sB, Вы писали:

TB>Здравствуйте, _hum_, Вы писали:


__>>а не нравится именно "an “eXpiring” value". то есть, если я все правильно понимаю, после использования std::move() дальше уже пользоваться объектом не всегда корректно (у него могли забрать ресурсы и сделать инвалидным).


TB>Нет конечно, никто, кроме деструктора, не имеет права делать объект инвалидным.


это по правилу хорошего тона? ну, так его не всегда соблюдают. а в общем случае ведь никто не запретит просто забрать данные у x-value способом, делающим объект невалидным для последующих операций.

TB>Объект переходит в нулевое состояние, скорее всего. Для вектора — это пустой вектор. Для классов, у которых нулевого состояния не предусмотрено — облом с крестовым мувом.


ну так для того, чтобы убедиться, что у вектора есть нулевое состояние и оно ничем не грозит, мне нужно лезть куда-то в доки и стандарты, в то время как swap делает это логически прозрачным.
Re[4]: как эффективно передать элементы из одного вектора в другой
От: B0FEE664  
Дата: 08.04.16 11:51
Оценка: :)
Здравствуйте, _hum_, Вы писали:

__>только тогда уже

__>const std::vector<int> & getConstRefToV(){ return x; }

только тогда уж:
const std::vector<int> & getConstRefToV() const { return x; }
И каждый день — без права на ошибку...
Re[17]: как эффективно передать элементы из одного вектора в
От: T4r4sB Россия  
Дата: 08.04.16 15:29
Оценка: :)
Здравствуйте, _hum_, Вы писали:

__>u-состоянием объекта назовем состояние, для которого единственная операция, корректность исполнения которой гарантирована — это удаление.


Нет смысла делать такой класс. Кончай придумывать бред, нет там такого.

__>остается определиться

__>1) что вы понимаете под "валиден" — в состоянии u- или null- ;

Я выше написал же, что значит "валиден".

__>2) где в специикации языка указан этот конракт (как для деструктора)


Я хз, стандарт не зубрил, где-то там.
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
как эффективно передать элементы из одного вектора в другой
От: sci_reseacher  
Дата: 07.04.16 13:49
Оценка:
Уважаемые форумчане!

Как наиболее эффективно (правильно) выполнить передачу (копирование, перемещение ... ) значений из одного вектора x (внутри объекта некоторого класса) в другой вектор y или z, который находиться вне класса в С++11?



class A {
      std::vector<int> x;
public:
      A(){
          x.resize(5,10);
      }
      const std::vector<int> & f(){
          return x ;
      }

      void g(std::vector<int>::iterator beg){
           std::copy(x.begin(),x.end(),beg);
      }
};

int main(){
     A a;
     std::vector<int> y(5);
     std::vector<int> z(5);
     y = a.f();
     a.g(z.begin());
     for(auto elem: y) std::cout << elem << " ";
     for(auto elem: z) std::cout << elem << " ";
}
Re: как эффективно передать элементы из одного вектора в дру
От: SaZ  
Дата: 07.04.16 15:56
Оценка:
Здравствуйте, sci_reseacher, Вы писали:

_>Уважаемые форумчане!


_>Как наиболее эффективно (правильно) выполнить передачу (копирование, перемещение ... ) значений из одного вектора x (внутри объекта некоторого класса) в другой вектор y или z, который находиться вне класса в С++11?



  Скрытый текст
_>

_>class A {
_>      std::vector<int> x;
_>public:
_>      A(){
_>          x.resize(5,10);
_>      }
_>      const std::vector<int> & f(){
_>          return x ;
_>      }

_>      void g(std::vector<int>::iterator beg){
_>           std::copy(x.begin(),x.end(),beg);
_>      }
_>};

_>int main(){
_>     A a;
_>     std::vector<int> y(5);
_>     std::vector<int> z(5);
_>     y = a.f();
_>     a.g(z.begin());
_>     for(auto elem: y) std::cout << elem << " ";
_>     for(auto elem: z) std::cout << elem << " ";
_>}
_>


Я бы юзал std::swap (для перемещения)
Отредактировано 07.04.2016 15:57 SaZ . Предыдущая версия .
Re[2]: как эффективно передать элементы из одного вектора в другой
От: _hum_ Беларусь  
Дата: 07.04.16 16:57
Оценка:
Здравствуйте, watchmaker, Вы писали:

W>Здравствуйте, sci_reseacher, Вы писали:


_>>Как наиболее эффективно (правильно) выполнить передачу (копирование, перемещение ... ) значений из одного вектора x (внутри объекта некоторого класса) в другой вектор y или z, который находиться вне класса в С++11?


W>Для перемещения — просто и без затей:
W>std::vector<int> z = std::move(a.x);


все-таки вариант
SaZ>Я бы юзал std::swap (для перемещения)

более симпатично выглядит (без опасения, что останется x-value)
Re[3]: как эффективно передать элементы из одного вектора в другой
От: T4r4sB Россия  
Дата: 07.04.16 17:26
Оценка:
Здравствуйте, _hum_, Вы писали:

__>все-таки вариант

SaZ>>Я бы юзал std::swap (для перемещения)

__>более симпатично выглядит (без опасения, что останется x-value)


Что такое x-value, и чем оно не нравится?
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Re[4]: как эффективно передать элементы из одного вектора в другой
От: _hum_ Беларусь  
Дата: 07.04.16 18:37
Оценка:
Здравствуйте, T4r4sB, Вы писали:

TB>Здравствуйте, _hum_, Вы писали:


__>>все-таки вариант

SaZ>>>Я бы юзал std::swap (для перемещения)

__>>более симпатично выглядит (без опасения, что останется x-value)


TB>Что такое x-value, и чем оно не нравится?


— An xvalue (an “eXpiring” value) also refers to an object, usually near the end of its lifetime (so that its resources may be moved, for example). An xvalue is the result of certain kinds of expressions involving rvalue references (8.3.2). [ Example: The result of calling a function whose return type is an rvalue reference is an xvalue. —end example ]



а не нравится именно "an “eXpiring” value". то есть, если я все правильно понимаю, после использования std::move() дальше уже пользоваться объектом не всегда корректно (у него могли забрать ресурсы и сделать инвалидным).
Re[5]: как эффективно передать элементы из одного вектора в другой
От: T4r4sB Россия  
Дата: 07.04.16 18:49
Оценка:
Здравствуйте, _hum_, Вы писали:

__>а не нравится именно "an “eXpiring” value". то есть, если я все правильно понимаю, после использования std::move() дальше уже пользоваться объектом не всегда корректно (у него могли забрать ресурсы и сделать инвалидным).


Нет конечно, никто, кроме деструктора, не имеет права делать объект инвалидным.
Объект переходит в нулевое состояние, скорее всего. Для вектора — это пустой вектор. Для классов, у которых нулевого состояния не предусмотрено — облом с крестовым мувом.
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Re[5]: как эффективно передать элементы из одного вектора в другой
От: watchmaker  
Дата: 07.04.16 19:47
Оценка:
Здравствуйте, _hum_, Вы писали:


__> и сделать инвалидным

Ну нет. Вектор, да и все остальные объекты стандартной библиотеки, гарантированно остается в валидном состоянии после move из него.


__> у него могли забрать ресурсы

А что обратную ситуацию не рассматриваешь?
Вот сделал я явно move из объекта, а он внутри через swap оказался реализован. Тогда swap не забрал ресурсы, лишь обменял. А раз при этом у ресурсов оказался новый владелец, то освободятся они только со смертью этого владельца. Что иногда может произойти ну через очень долгое время. И закиснет где-нибудь в программе указатель на пару гигабайт памяти, на массив дескрипторов GUI-библиотеки или ещё на что-то подобное. Они, конечно, потом освободятся — утечки не будет, но куда лучше будет этот гигабайт памяти сразу освободить как станет ненужным, а не откладывать это действие на конец программы.
The Drawbacks of Implementing Move Assignment in Terms of Swap — этот негативный сценарий, конечно, реализуется не слишком часто (и поэтому через swap реализовывать move в общем-то не запрещено), но встречается он всё же чаще, чем невалидный std::vector после перемещения из него.
Re[6]: как эффективно передать элементы из одного вектора в другой
От: _hum_ Беларусь  
Дата: 07.04.16 21:00
Оценка:
Здравствуйте, watchmaker, Вы писали:

W>Здравствуйте, _hum_, Вы писали:



__>> и сделать инвалидным

W>Ну нет. Вектор, да и все остальные объекты стандартной библиотеки, гарантированно остается в валидном состоянии после move из него.

еще раз повторюсь, это надо лезть и читать, а что ж там остается от вектора после его std::move другому объекту, и как с этим жить, тогда как swap делает то же смое, при этом не приводя к появлению таких вопросов.


__>> у него могли забрать ресурсы

W>А что обратную ситуацию не рассматриваешь?
W>Вот сделал я явно move из объекта, а он внутри через swap оказался реализован. Тогда swap не забрал ресурсы, лишь обменял. А раз при этом у ресурсов оказался новый владелец, то освободятся они только со смертью этого владельца.

погодите, речь про swap с пустым вектором. то есть,
std::vector<int> V_1(1000) ;
std::vector<int> V_2;

// V_2 = std::move(V_1); 
V_2.swap(V_1);
Re[7]: как эффективно передать элементы из одного вектора в другой
От: watchmaker  
Дата: 07.04.16 21:07
Оценка:
Здравствуйте, _hum_, Вы писали:

__>это по правилу хорошего тона? ну, так его не всегда соблюдают. а в общем случае ведь никто не запретит просто забрать данные у x-value способом, делающим объект невалидным для последующих операций.


Бредовый пример. Мне кажется, что это всё равно, как если бы написать в своём контейнере что-то вроде
struct MyArray { 
  ...
  char* begin() const {
    return (char*)(rand() % 2 ? 0 : "begin");
  }
  char* end() const {
    return (char*)"end";
  }
};
а потом жаловаться, что range-based-for с таким классом не работает (да ещё и глючит каждый раз по разному), а поэтому range-based-for плохой и использовать его не надо.
А то ведь в стандарте тоже соглашения об смысле методов begin и end — не более чем "правила хорошего тона".


__>ну так для того, чтобы убедиться, что у вектора есть нулевое состояние и оно ничем не грозит, мне нужно лезть куда-то в доки и стандарты, в то время как swap делает это логически прозрачным.

А swap для двух объектов произвольного типа что делает? Неужели обменивает их состояние? Откуда у тебя такая уверенность в этом? Сомневаюсь, что разумный человек может быть в этом уверен без "залезания в доки" или без просмотра исходников. Ведь обменивающее поведение swap — не более чем правило хорошего тона!
Re[7]: как эффективно передать элементы из одного вектора в другой
От: watchmaker  
Дата: 07.04.16 21:11
Оценка:
Здравствуйте, _hum_, Вы писали:

__>погодите, речь про swap с пустым вектором. то есть,

А с непустым что? Никогда не делал присваивания непустому вектору? Вон даже у автора темы в первом сообщении такая строчка есть.
Re[8]: как эффективно передать элементы из одного вектора в другой
От: _hum_ Беларусь  
Дата: 07.04.16 21:39
Оценка:
Здравствуйте, watchmaker, Вы писали:

W>Здравствуйте, _hum_, Вы писали:


__>>это по правилу хорошего тона? ну, так его не всегда соблюдают. а в общем случае ведь никто не запретит просто забрать данные у x-value способом, делающим объект невалидным для последующих операций.


W>Бредовый пример. Мне кажется, что это всё равно, как если бы написать в своём контейнере что-то вроде
struct MyArray { 
W>  ...
W>  char* begin() const {
W>    return (char*)(rand() % 2 ? 0 : "begin");
W>  }
W>  char* end() const {
W>    return (char*)"end";
W>  }
W>};
а потом жаловаться, что range-based-for с таким классом не работает (да ещё и глючит каждый раз по разному), а поэтому range-based-for плохой и использовать его не надо.

W>А то ведь в стандарте тоже соглашения об смысле методов begin и end — не более чем "правила хорошего тона".

не понял вашу мысль. моя состояла в том, что move-assignement operator/move copy constructor, вообще говоря, не обязаны оставлять переданное им x-value в валидном состоянии (порой очень муторно заводить для объекта "нулевое состояние" и переводить его туда. проще забрать данные и "давай, до свидания"). в конце-концов, в чем тогда выгода вводить eXpired-value, если все равно с ним нужно цацкаться, как с обычным l-value?

__>>ну так для того, чтобы убедиться, что у вектора есть нулевое состояние и оно ничем не грозит, мне нужно лезть куда-то в доки и стандарты, в то время как swap делает это логически прозрачным.

W>А swap для двух объектов произвольного типа что делает? Неужели обменивает их состояние? Откуда у тебя такая уверенность в этом? Сомневаюсь, что разумный человек может быть в этом уверен без "залезания в доки" или без просмотра исходников. Ведь обменивающее поведение swap — не более чем правило хорошего тона!

речь шла не о генерализированной функции swap, а о методе. а это значит, никаких вопросов быть не должно — если есть такой метод, значит, есть корректная реализация обмена для векторов.
Re[8]: как эффективно передать элементы из одного вектора в другой
От: _hum_ Беларусь  
Дата: 07.04.16 21:40
Оценка:
Здравствуйте, watchmaker, Вы писали:

W>Здравствуйте, _hum_, Вы писали:


__>>погодите, речь про swap с пустым вектором. то есть,

W>А с непустым что? Никогда не делал присваивания непустому вектору? Вон даже у автора темы в первом сообщении такая строчка есть.

с непустым так делать не нужно, ибо бессмысленно в контексте беседы (переместить объект)
Re[7]: как эффективно передать элементы из одного вектора в
От: T4r4sB Россия  
Дата: 08.04.16 07:29
Оценка:
Здравствуйте, _hum_, Вы писали:

__>это по правилу хорошего тона? ну, так его не всегда соблюдают. а в общем случае ведь никто не запретит просто забрать данные у x-value способом, делающим объект невалидным для последующих операций.


Нет, это по правилу, без соблюдения которого класс не считается правильным.
Я не знаю, кто его не соблюдает. Кто-то может и в деструкторе насрать и не убрать, это не значит, что теперь нельзя пользоваться деструкторами.

Подумай сам, если объект после мува невалиден, то как у него будет вызываться деструктор? Ведь компилятору пофиг, делали объекту мув. или нет, он по любому будет его деструктировать.
Так что если увидишь инвалидирующий мув, то пинай этого программиста.
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Отредактировано 08.04.2016 7:31 T4r4sB . Предыдущая версия .
Re[8]: как эффективно передать элементы из одного вектора в
От: _hum_ Беларусь  
Дата: 08.04.16 08:26
Оценка:
Здравствуйте, T4r4sB, Вы писали:

TB>Здравствуйте, _hum_, Вы писали:


__>>это по правилу хорошего тона? ну, так его не всегда соблюдают. а в общем случае ведь никто не запретит просто забрать данные у x-value способом, делающим объект невалидным для последующих операций.


TB>Нет, это по правилу, без соблюдения которого класс не считается правильным.


что такое "правильным"?

TB>Я не знаю, кто его не соблюдает. Кто-то может и в деструкторе насрать и не убрать, это не значит, что теперь нельзя пользоваться деструкторами.


не совсем верная аналогия. у деструктора однозначная семантика — завершать существование объекта, а вот у move она расплывчатая (перемещать и оставлять объект только для удаления или все же оставлять его в "нуль состоянии" с возможностью продолжить работу с объектом).

TB>Подумай сам, если объект после мува невалиден, то как у него будет вызываться деструктор? Ведь компилятору пофиг, делали объекту мув. или нет, он по любому будет его деструктировать.


вы наверное не поняли. невалидный не в смысле "даже удалиться не сможет без ошибок",а в смысле — единственное, на что он способен — умереть (на то он и expired). иными словами, он переведен в конечное состояние, из которого нет выхода на нормальную работу (ну, не знаю, например, объект класса, который логически не допускает конструктора по умолчанию, и у которого все нужные для работы данные были перемещены)

TB>Так что если увидишь инвалидирующий мув, то пинай этого программиста.


ну так это и означает, что неинвалидирующий мув — это "по правилу хорошего тона", а значит, нет никаких гарантий
Re[9]: как эффективно передать элементы из одного вектора в
От: T4r4sB Россия  
Дата: 08.04.16 08:49
Оценка:
Здравствуйте, _hum_, Вы писали:

__>что такое "правильным"?


Правильным это значит правильным.

__>не совсем верная аналогия. у деструктора однозначная семантика — завершать существование объекта, а вот у move она расплывчатая (перемещать и оставлять объект только для удаления или все же оставлять его в "нуль состоянии" с возможностью продолжить работу с объектом).


TB>>Подумай сам, если объект после мува невалиден, то как у него будет вызываться деструктор? Ведь компилятору пофиг, делали объекту мув. или нет, он по любому будет его деструктировать.


__>вы наверное не поняли. невалидный не в смысле "даже удалиться не сможет без ошибок",а в смысле — единственное, на что он способен — умереть (на то он и expired). иными словами, он переведен в конечное состояние, из которого нет выхода на нормальную работу (ну, не знаю, например, объект класса, который логически не допускает конструктора по умолчанию, и у которого все нужные для работы данные были перемещены)


Это какой-то надуманный класс. Если есть нулевое состояние, то никто не мешает конструировать по умолчанию в него и делать метод вывода из него.

TB>>Так что если увидишь инвалидирующий мув, то пинай этого программиста.


__>ну так это и означает, что неинвалидирующий мув — это "по правилу хорошего тона", а значит, нет никаких гарантий


Насрать в деструкторе — это тоже "правило хорошего тона"? Тебе какое слово нужно, я просто не понимаю? У тебя кодовое слово "мамой клянусь, что всё збс будет"?
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Re[2]: как эффективно передать элементы из одного вектора в другой
От: sci_reseacher  
Дата: 08.04.16 09:53
Оценка:
Есть внутренний вектор с данными (правят их методы класса),

требуется только читать эти данные вне (править нельзя).

Вот так будет верно?

class A {
std::vector<int> x; // данные здесь
public:
A(const size_t n){ x.resize(n,25); }
const std::vector<int> & getRefToV(){ return x; }
};

int main(){
    A a(5);
    const std::vector<int> & ref_to_x = a.getRefToV(); // здесь просто ссылка
    for( const auto & e: ref_to_x) { std::cout << e << ' ' ; }
}
$ c++ -std=c++11 t2.cpp -o t2 && ./t2
25 25 25 25 25
Re[10]: как эффективно передать элементы из одного вектора в
От: _hum_ Беларусь  
Дата: 08.04.16 10:35
Оценка:
Здравствуйте, T4r4sB, Вы писали:

TB>Здравствуйте, _hum_, Вы писали:


__>>что такое "правильным"?


TB>Правильным это значит правильным.


правильность без указания конкретных критериев, является субъективным понятием.

__>>не совсем верная аналогия. у деструктора однозначная семантика — завершать существование объекта, а вот у move она расплывчатая (перемещать и оставлять объект только для удаления или все же оставлять его в "нуль состоянии" с возможностью продолжить работу с объектом).


TB>>>Подумай сам, если объект после мува невалиден, то как у него будет вызываться деструктор? Ведь компилятору пофиг, делали объекту мув. или нет, он по любому будет его деструктировать.


__>>вы наверное не поняли. невалидный не в смысле "даже удалиться не сможет без ошибок",а в смысле — единственное, на что он способен — умереть (на то он и expired). иными словами, он переведен в конечное состояние, из которого нет выхода на нормальную работу (ну, не знаю, например, объект класса, который логически не допускает конструктора по умолчанию, и у которого все нужные для работы данные были перемещены)


TB>Это какой-то надуманный класс. Если есть нулевое состояние, то никто не мешает конструировать по умолчанию в него и делать метод вывода из него.


а если нет нулевого состояния? ну не имеет оно логического смысла/вредно/опасно/неудобно?

TB>>>Так что если увидишь инвалидирующий мув, то пинай этого программиста.


__>>ну так это и означает, что неинвалидирующий мув — это "по правилу хорошего тона", а значит, нет никаких гарантий


TB>Насрать в деструкторе — это тоже "правило хорошего тона"? Тебе какое слово нужно, я просто не понимаю? У тебя кодовое слово "мамой клянусь, что всё збс будет"?


важна однозначность трактовки. если я вижу vec_1.swap(vec_2), где vec_1 пустой, то я точно знаю, что произойдет (нет никаких домыслов, переведется ли он в нулевое состояние или инвалидное, будет ли это нулевое совпадать с обычным состояние впервые созданного по дефолту объекта или нет. и проч.)
Re[11]: как эффективно передать элементы из одного вектора в
От: T4r4sB Россия  
Дата: 08.04.16 10:52
Оценка:
Здравствуйте, _hum_, Вы писали:

__>правильность без указания конкретных критериев, является субъективным понятием.


Оставляет объект в правильном состоянии, ты не знаешь, что такое правильное состояние объекта?

__>а если нет нулевого состояния? ну не имеет оно логического смысла/вредно/опасно/неудобно?


Тогда мув-конструктор невозможен, например. Потому что во что переводить второй объект?

__>важна однозначность трактовки. если я вижу vec_1.swap(vec_2), где vec_1 пустой, то я точно знаю, что произойдет (нет никаких домыслов, переведется ли он в нулевое состояние или инвалидное, будет ли это нулевое совпадать с обычным состояние впервые созданного по дефолту объекта или нет. и проч.)


Однозначно промуванному вектору можно вызвать клиар/ресайз и дальше работать с нужным числом элементов.
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Re[12]: как эффективно передать элементы из одного вектора в
От: _hum_ Беларусь  
Дата: 08.04.16 11:21
Оценка:
Здравствуйте, T4r4sB, Вы писали:

TB>Здравствуйте, _hum_, Вы писали:


__>>правильность без указания конкретных критериев, является субъективным понятием.


TB>Оставляет объект в правильном состоянии, ты не знаешь, что такое правильное состояние объекта?


нет а можете рассказать?

__>>а если нет нулевого состояния? ну не имеет оно логического смысла/вредно/опасно/неудобно?


TB>Тогда мув-конструктор невозможен, например. Потому что во что переводить второй объект?


невозможен или "попахивает" с точки зрения "правил хорошего тона"? как вариант — второй объект переводится в "expired-state" (с гарантией правильного удаления и только)

T4r4sB, я согласен в с вами, что неплохо было бы придерживаться правила — разрешать применять move только тогда, когда
1) объект имеет null-state в понимании :

Andrzej's C++ blog: Null-state

Properties of null-state
In general, there are only two useful operations that you can successfully perform on such object: assign it a normal (non-null) value and safely destroy it.

(это же вы имели в виду?)

2) перемeщение приводит к переводу объекта в null-state

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


__>>важна однозначность трактовки. если я вижу vec_1.swap(vec_2), где vec_1 пустой, то я точно знаю, что произойдет (нет никаких домыслов, переведется ли он в нулевое состояние или инвалидное, будет ли это нулевое совпадать с обычным состояние впервые созданного по дефолту объекта или нет. и проч.)


TB>Однозначно промуванному вектору можно вызвать клиар/ресайз и дальше работать с нужным числом элементов.


ну для этого нужно лезть в доки и узнавать, что это так вот теперь, после разговоров с вами и заверений, что для stl указанные выше пункты выполняются + null state совпадает с первоначальным состоянием только что сконструированного по дефолту объекта, я смогу спокойно применять мув вместо свопа для векторов и других объектов stl
Re[13]: как эффективно передать элементы из одного вектора в
От: T4r4sB Россия  
Дата: 08.04.16 11:41
Оценка:
Здравствуйте, _hum_, Вы писали:

__>нет а можете рассказать?


Я хз, как тогда можно на С++ писать. Все методы класса предполагают, что между его элементами есть некие соглашения типа "поле "размер" не равно нулю тогда и только тогда, когда поле "указатель" указывает на блок данных нужного размеры, на который больше никто данного типа не указывает" итд, без соглашений методы накроются, программу разнесёт нахрен.

TB>>Тогда мув-конструктор невозможен, например. Потому что во что переводить второй объект?


__>невозможен или "попахивает" с точки зрения "правил хорошего тона"? как вариант — второй объект переводится в "expired-state" (с гарантией правильного удаления и только)


Во что он будет переводить, чисто логически?
Не, можно делать копию, кстати, да. Это как раз коректно, но не по правилам хорошего тона.
Но валидность гарантируется.

__>но, во-первых, в текущем варианте языка это не отслеживается, а значит, развязывает руки


А кто отслеживает, что ты в деструкторе не накосячишь?

__>а во-вторых, речь же шла не об этом, а о том, что вариант со свопом более нагляден и однозначен.


Своп не нагляден, когда нужен обмен. Потому что своп подразумевает, что мы хотели своп, а не просто переместить.

__>ну для этого нужно лезть в доки и узнавать, что это так


Это для любого класса верно. Только вместо ресайза подставь другой "метод, доступный из любого валидного состояния". Понятно, что обращаться по индексу 100500 у промуванного вектора не стоит.
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Re[2]: как эффективно передать элементы из одного вектора в другой
От: Kernan Ниоткуда https://rsdn.ru/forum/flame.politics/
Дата: 08.04.16 11:58
Оценка:
Здравствуйте, watchmaker, Вы писали:

W>Или через ref-qulifiers отдать выбор нужной перегрузки компилятору:

using V = std::vector<int>;

W>  const V& CopyX() const& {
W>    return x;
W>  }
  
W>  V&& CopyX() && {
W>    return std::move(x);
W>  }
  
W>  void CopyTo(V& target) const& {
W>    target.assign(x.begin(), x.end());
W>  }
  
W>  void CopyTo(V& target) && {
W>    target.swap(x);
W>  }
W>

W>Тогда, например, получится [ccode]

Какой прок от квалификаторов?
Sic luceat lux!
Re[14]: как эффективно передать элементы из одного вектора в
От: _hum_ Беларусь  
Дата: 08.04.16 12:38
Оценка:
Здравствуйте, T4r4sB, Вы писали:

TB>Здравствуйте, _hum_, Вы писали:



TB>>>Тогда мув-конструктор невозможен, например. Потому что во что переводить второй объект?


__>>невозможен или "попахивает" с точки зрения "правил хорошего тона"? как вариант — второй объект переводится в "expired-state" (с гарантией правильного удаления и только)


TB>Во что он будет переводить, чисто логически?


чисто логически в "объект с нарушенной целостностью (incosistent)" — то, что можно только выбросить, но никак не пытаться вновь использовать (какой-то аналог объекта, выбросившего исключение, или объекта, вызов метода set для которого завершился с ненулевым кодом ошибки)

TB>Не, можно делать копию, кстати, да. Это как раз коректно, но не по правилам хорошего тона.

TB>Но валидность гарантируется.

вы про какую копию? оставлять копию исходного перемещенного объекта? ну так зачем тогда вообще понятие перемещения?

__>>но, во-первых, в текущем варианте языка это не отслеживается, а значит, развязывает руки


TB>А кто отслеживает, что ты в деструкторе не накосячишь?


понимаете, тут речь о степени косяков. вроде, есть понятие контракта. так вот переопределение деструктора имеет однозначный контракт — вы подписываетесь под тем, что берете отвественность за корректную деинициализацию объекта перед его физическим удалением. и другой человек ожидает от подписавшего этот конракт очевидных действий.
с move такого очевидного однозначного контракта нет, а значит, один будет при его использовании считать, что подписывается на одно, а другой — на другое. итого — misunderstanding.

так вот, если кто-то нарушает однозначный контракт (нарушает требование контракта о корректной деинициализации объекта в деструкторе) — это ошибка первого рода (криворукий программист), а вот если начинаются ошибки из-за отсутствия однозначного контракта и его требований — это уже совсем другого порядка ошибки.

__>>а во-вторых, речь же шла не об этом, а о том, что вариант со свопом более нагляден и однозначен.


TB>Своп не нагляден, когда нужен обмен. Потому что своп подразумевает, что мы хотели своп, а не просто переместить.


но для пустого объекта он в точности по логике совпадает с перемещением

__>>ну для этого нужно лезть в доки и узнавать, что это так


TB>Это для любого класса верно. Только вместо ресайза подставь другой "метод, доступный из любого валидного состояния". Понятно, что обращаться по индексу 100500 у промуванного вектора не стоит.


нее, одно дело почитать спецификацию функции, и совсем другое искать в стандартах и проч. какие-то там гарантии чего-то..
Re[15]: как эффективно передать элементы из одного вектора в
От: T4r4sB Россия  
Дата: 08.04.16 12:43
Оценка:
Здравствуйте, _hum_, Вы писали:

__>чисто логически в "объект с нарушенной целостностью (incosistent)" — то, что можно только выбросить, но никак не пытаться вновь использовать (какой-то аналог объекта, выбросившего исключение, или объекта, вызов метода set для которого завершился с ненулевым кодом ошибки)


Ты понимаешь, что объекту с нарушенной целостностью нельзя вызывать деструктор, что противоречит определению мува? Ты понимаешь, что "выбросить" и вызвать деструктор — это разные вещи?

__>вы про какую копию? оставлять копию исходного перемещенного объекта? ну так зачем тогда вообще понятие перемещения?


Ну иначе для объекта-без-нулевого-состояния мув не сделать никак.

__>понимаете, тут речь о степени косяков. вроде, есть понятие контракта. так вот переопределение деструктора имеет однозначный контракт — вы подписываетесь под тем, что берете отвественность за корректную деинициализацию объекта перед его физическим удалением. и другой человек ожидает от подписавшего этот конракт очевидных действий.

__>с move такого очевидного однозначного контракта нет, а значит, один будет при его использовании считать, что подписывается на одно, а другой — на другое. итого — misunderstanding.

С мув есть однозначный контракт, что объект остаётся валиден. Но точное значение объекта тебе никто не предскажет.

__>но для пустого объекта он в точности по логике совпадает с перемещением


Давай называть красное белым?
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Re[16]: как эффективно передать элементы из одного вектора в
От: _hum_ Беларусь  
Дата: 08.04.16 13:01
Оценка:
Здравствуйте, T4r4sB, Вы писали:

TB>Здравствуйте, _hum_, Вы писали:


__>>чисто логически в "объект с нарушенной целостностью (incosistent)" — то, что можно только выбросить, но никак не пытаться вновь использовать (какой-то аналог объекта, выбросившего исключение, или объекта, вызов метода set для которого завершился с ненулевым кодом ошибки)


TB>Ты понимаешь, что объекту с нарушенной целостностью нельзя вызывать деструктор, что противоречит определению мува? Ты понимаешь, что "выбросить" и вызвать деструктор — это разные вещи?


чтоб не спорить на пустом месте, давайте я введу определение:

u-состоянием объекта назовем состояние, для которого единственная операция, корректность исполнения которой гарантирована — это удаление.

вот в моем понимании минимальное требование к move — перевод в u-состояние. ваше же требование (которое мне симпатично, но от этого не становится едиснтвенным) — перевод в null-состояние.
итого, как минимум два возможных контракта на применение move.

__>>вы про какую копию? оставлять копию исходного перемещенного объекта? ну так зачем тогда вообще понятие перемещения?


TB>Ну иначе для объекта-без-нулевого-состояния мув не сделать никак.


сделать можно , переведя в u-состояние

__>>понимаете, тут речь о степени косяков. вроде, есть понятие контракта. так вот переопределение деструктора имеет однозначный контракт — вы подписываетесь под тем, что берете отвественность за корректную деинициализацию объекта перед его физическим удалением. и другой человек ожидает от подписавшего этот конракт очевидных действий.

__>>с move такого очевидного однозначного контракта нет, а значит, один будет при его использовании считать, что подписывается на одно, а другой — на другое. итого — misunderstanding.

TB>С мув есть однозначный контракт, что объект остаётся валиден. Но точное значение объекта тебе никто не предскажет.


остается определиться
1) что вы понимаете под "валиден" — в состоянии u- или null- ;
2) где в специикации языка указан этот конракт (как для деструктора)

__>>но для пустого объекта он в точности по логике совпадает с перемещением


TB>Давай называть красное белым?


если только есть вероятность, что в дальнейшем пустой вектор может превратиться в непустой перед свопом.
Re[18]: как эффективно передать элементы из одного вектора в
От: _hum_ Беларусь  
Дата: 08.04.16 16:43
Оценка:
Здравствуйте, T4r4sB, Вы писали:

TB>Здравствуйте, _hum_, Вы писали:


__>>u-состоянием объекта назовем состояние, для которого единственная операция, корректность исполнения которой гарантирована — это удаление.


TB>Нет смысла делать такой класс. Кончай придумывать бред, нет там такого.


не класс, а состояние объекта (вы вообще читаете, что я пишу?)

__>>остается определиться

__>>1) что вы понимаете под "валиден" — в состоянии u- или null- ;

TB>Я выше написал же, что значит "валиден".


мне перелопачивать все ветки, а вам лишь написать u- или null- (конечно, при условии, что вы поняли, о чем речь)

__>>2) где в специикации языка указан этот конракт (как для деструктора)


TB>Я хз, стандарт не зубрил, где-то там.


и вы, действительно, это видели своими глазами (чтобы в стандарте прописывалось, что применение move к l-value нацелено на перемещение из него данных с переводом при этом его в null-состояние)?
Re[19]: как эффективно передать элементы из одного вектора в
От: T4r4sB Россия  
Дата: 08.04.16 17:54
Оценка:
Здравствуйте, _hum_, Вы писали:

__>не класс, а состояние объекта (вы вообще читаете, что я пишу?)


А ты вообще понимаешь, что я пишу? Нет смысла делать такой класс. У которого есть такое состояние. Потому что если сделали такое состояние, то его же можно использовать как "нулевое".

__>мне перелопачивать все ветки, а вам лишь написать u- или null- (конечно, при условии, что вы поняли, о чем речь)


Это было в то же сообщении, на которое ты отвечал, причём в этом же ответе ты спросил "что такое валидное состояние"
И это ты ещё меня обвиняешь в том, что я не читаю, что ты пишешь.

__>и вы, действительно, это видели своими глазами (чтобы в стандарте прописывалось, что применение move к l-value нацелено на перемещение из него данных с переводом при этом его в null-состояние)?


Не в null-состояние, а в какое-то валидное состояние.
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Re[20]: как эффективно передать элементы из одного вектора в
От: _hum_ Беларусь  
Дата: 08.04.16 18:44
Оценка:
Здравствуйте, T4r4sB, Вы писали:

TB>Здравствуйте, _hum_, Вы писали:


__>>не класс, а состояние объекта (вы вообще читаете, что я пишу?)


TB>А ты вообще понимаешь, что я пишу? Нет смысла делать такой класс. У которого есть такое состояние. Потому что если сделали такое состояние, то его же можно использовать как "нулевое".


T4r4sB, я предлагал строго очертить границы понятий, которыми пользуемся в разговоре, чтобы, во-первых, понимать одно и то же под одним и тем же термином, а во-вторых, не скатываться в демагогию.
для этого я привел точные определения понятий

null-состояние объекта как состояние, для которого

In general, there are only two useful operations that you can successfully perform on such object: assign it a normal (non-null) value and safely destroy it.

и u-состояние — состояние

для которого единственная операция, корректность исполнения которой гарантирована — это удаление.


и пытался ими оперировать, но вы опять ушли в какое-то эфемерное "валидное состояние". раз так, будьте добры аналогичным образом дать его определение.
Re[21]: как эффективно передать элементы из одного вектора в
От: T4r4sB Россия  
Дата: 08.04.16 19:00
Оценка:
Здравствуйте, _hum_, Вы писали:


__>T4r4sB, я предлагал строго очертить границы понятий, которыми пользуемся в разговоре, чтобы, во-первых, понимать одно и то же под одним и тем же термином, а во-вторых, не скатываться в демагогию.


А, хочешь поговорить о сущности понятия "валидное состояние" — это не ко мне, я ляля не умею. Я всё сказал, что мог, твои страхи перед мувом безосновательны.
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.