powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / Идиома copy-on-swap С++
39 сообщений из 39, показаны все 2 страниц
Идиома copy-on-swap С++
    #38877483
Фотография Станислав Клевцов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Здравствуйте.

Есть описание идиомы на WIKIPEDIA
https://ru.wikipedia.org/wiki/Идиома_copy-and-swap

Кто - нибудь может объяснить тоже самое, но только в двух словах и более простом языком ?
...
Рейтинг: 0 / 0
Идиома copy-on-swap С++
    #38877507
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Станислав Клевцов,

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

2) Решение.
Сначала создать временный объект, копию того из которого присваивается.
Если на этом этапе произойдет исключение, то текущий объект пока еще не изменен и несогласованности нет.
Потом производится обмен полей временного объекта с полями конечного объекта путем простого побайтового копирования. Такое копирование не может выбросить исключение и оно почти не вносит дополнительных расходов.
На завершающем этапе присвоения вызовется деструктор временного объекта и очистит поля ранее принадлежавшие конечному объекту.

Таким образом данное решение позволяет всегда иметь объекты в согласованном состоянии.
...
Рейтинг: 0 / 0
Идиома copy-on-swap С++
    #38877509
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Иными словами проблема высосана из пальца. И ее решение хоть и достаточно элегантно, но не имеет смысла.
...
Рейтинг: 0 / 0
Идиома copy-on-swap С++
    #38877514
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
White OwlИными словами проблема высосана из пальца
Это вполне реальная проблема.
Конечно с точки зрения С-шника, необходимость вручную убирать выделенную память не является проблемой.
Но в С++ концепция другая - главная цель создания С++ - переложить всю ручную работу на компилятор.
Данная идиома показывает как это сделать проще всего для конкретной задачи.
...
Рейтинг: 0 / 0
Идиома copy-on-swap С++
    #38877515
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly MoskovskyWhite OwlИными словами проблема высосана из пальца
Это вполне реальная проблема.
Конечно с точки зрения С-шника, необходимость вручную убирать выделенную память не является проблемой.
Но в С++ концепция другая - главная цель создания С++ - переложить всю ручную работу на компилятор.
Данная идиома показывает как это сделать проще всего для конкретной задачи.Вот я так и чувствовал что на мой фундамент начнут кивать...

Подразумевается что есть класс:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
class A {
   string *str1, *str2;
   A() {
      str1 = new string();
      str2 = new string();
   }

   A& operator=(const A & a) {
     str1 = new string(a.str1);  // can fail
     str2 = new string(a.str2);  // can fail
     return *this;
  }

  ~A() {
     delete str1;
     delete str2;
  }

  void set_data( ... ) {....} // do something
};



A a, b;
a.set_data ( );

try {
   b=a;
} catch (Exception e) {
   delete b;
}


И теперь, если одно из присвоений внутри operator=() упало, то в последней строке состояние b будет неопределенным. Было заполнено str1? str2? или еще что-то упало? В каком объеме надо очищать b?
Я правильно понимаю вашу проблему?
...
Рейтинг: 0 / 0
Идиома copy-on-swap С++
    #38877516
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
White OwlИ теперь, если одно из присвоений внутри operator=() упало, то в последней строке состояние b будет неопределенным. Было заполнено str1? str2? или еще что-то упало? В каком объеме надо очищать b?
Я правильно понимаю вашу проблему?
Да, обычно новички каждый раз заново придумывают как реализовать оператор =.
И чаще всего, как и в вашем случае, он неверно реализован.
Например, не удаляется предыдущее значение полей.
И прочее.
Чтобы не придумывать каждый раз, данная идиома показывает как тривиально реализовать =, который автоматически не имеет указанных проблем и заодно не требует перехвата исключений.
...
Рейтинг: 0 / 0
Идиома copy-on-swap С++
    #38877520
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly MoskovskyWhite OwlИ теперь, если одно из присвоений внутри operator=() упало, то в последней строке состояние b будет неопределенным. Было заполнено str1? str2? или еще что-то упало? В каком объеме надо очищать b?
Я правильно понимаю вашу проблему?
Да, обычно новички каждый раз заново придумывают как реализовать оператор =.
И чаще всего, как и в вашем случае, он неверно реализован.
Например, не удаляется предыдущее значение полей.
И прочее.
Чтобы не придумывать каждый раз, данная идиома показывает как тривиально реализовать =, который автоматически не имеет указанных проблем и заодно не требует перехвата исключений.Не требует? Точно?
То есть ты утверждаешь что если оператор присваивания переписать через copy-and-swap, то исключения возникнуть не смогут?
А исключения которые могут возникнуть внутри конструктора копирования (и по тем-же самым причинам) ты в расчет не принимаешь?
...
Рейтинг: 0 / 0
Идиома copy-on-swap С++
    #38877521
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
White OwlТо есть ты утверждаешь что если оператор присваивания переписать через copy-and-swap, то исключения возникнуть не смогут?
Могут.
White OwlА исключения которые могут возникнуть внутри конструктора копирования (и по тем-же самым причинам) ты в расчет не принимаешь?
Да, не принимаю, т.к. это забота конструктора копирования (который по-любому нужно реализовать если требуется оператор=), и к тому же в правильно написанном конструкторе компилятор сам заботится о исключениях.
...
Рейтинг: 0 / 0
Идиома copy-on-swap С++
    #38877525
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly MoskovskyWhite OwlТо есть ты утверждаешь что если оператор присваивания переписать через copy-and-swap, то исключения возникнуть не смогут?
Могут.Я рад что ты это понимаешь.

Anatoly MoskovskyWhite OwlА исключения которые могут возникнуть внутри конструктора копирования (и по тем-же самым причинам) ты в расчет не принимаешь?
Да, не принимаю, т.к. это забота конструктора копирования (который по-любому нужно реализовать если требуется оператор=), А вот это очень даже плохо. На этом вы, любимые мои сипипифилы, и горите.

Во первых, никто не гарантирует что конструктор копирования написан правильно (а не точно так как я показал в примере кривого оператора присваивания).
Во вторых, для copy-and-swap надо еще написать правильный метод swap. Что тоже не всегда тривиально.
В третьих, даже если конструктор копирования и swap() написаны правильно - конструктор все равно может упасть. И значит каждый a=b; надо оборачивать в try{}catch (или ловить исключение выше по стеку).
Это были минусы copy-and-swap. В плюсах:
- при наличии обоих методов: конструктора копирования и оператора присваивания, если один метод вызывает другой то жить чуть проще становится. Что однако нивелируется необходимостью написания метода swap()...
- если a=b все-же упала, то мы точно знаем что a это "пустой" объект.

Однако! Если правильно написать operator=() то и проблемы несогласованного состояния тоже никогда не будет. А если неправильно написать конструктор копирования, то проблема несогласованного состояния все равно возникнет.


Вывод: используешь ты этот патерн или нет разницы никакой нет. Без него тебе надо продуманно писать operator=() и конструктор копирования. С ним тебе надо продуманно писать конструктор копирования и swap(). Работы в итоге получается практически одинаково. Упасть на a=b можно в обоих случаях и с одинаковым результатом.
...
Рейтинг: 0 / 0
Идиома copy-on-swap С++
    #38877527
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
White OwlВо первых, никто не гарантирует что конструктор копирования написан правильно (а не точно так как я показал в примере кривого оператора присваивания).
Написать конструктор правильно намного проще, чем присвоение.

White OwlВо вторых, для copy-and-swap надо еще написать правильный метод swap. Что тоже не всегда тривиально.
Нет. Всегда тривиально.
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
friend void swap(T& a, T& b)
{
	using std::swap;
	swap(a.f1, b.f1);
	swap(a.f2, b.f2);
	swap(a.f3, b.f3);
}


Если это нетривиально, то что тогда тривиально ))
White OwlВ третьих, даже если конструктор копирования и swap() написаны правильно - конструктор все равно может упасть. И значит каждый a=b; надо оборачивать в try{}catch (или ловить исключение выше по стеку).
Нет. Не надо оборачивать ничего. Исключения ловятся там где это задумано по дизайну приложения, а не в операторе присвоения из-за неумения написать его правильно - это и есть цель которая достигается данной идиомой

White OwlВывод: используешь ты этот патерн или нет разницы никакой нет. Без него тебе надо продуманно писать operator=() и конструктор копирования. С ним тебе надо продуманно писать конструктор копирования и swap(). Работы в итоге получается практически одинаково. Упасть на a=b можно в обоих случаях и с одинаковым результатом.
Садитесь два. Изучайте заново материал ))

ЗЫ. White Owl, критика всегда уместна. Критиковать можно даже то, в чем не разбираешься. Но не надо облекать это в форму советов бывалого и тем более заниматься дартаньянизмом :)
...
Рейтинг: 0 / 0
Идиома copy-on-swap С++
    #38877549
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly MoskovskyWhite OwlВо первых, никто не гарантирует что конструктор копирования написан правильно (а не точно так как я показал в примере кривого оператора присваивания).
Написать конструктор правильно намного проще, чем присвоение.Почему? В чем разница?

Anatoly MoskovskyWhite OwlВо вторых, для copy-and-swap надо еще написать правильный метод swap. Что тоже не всегда тривиально.
Нет. Всегда тривиально.
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
friend void swap(T& a, T& b)
{
	using std::swap;
	swap(a.f1, b.f1);
	swap(a.f2, b.f2);
	swap(a.f3, b.f3);
}


Если это нетривиально, то что тогда тривиально ))Тривиально это отсутствие метода. А в данном случае нетривиально то, что надо не забыть перечислить все поля. И это только в минимуме, если используемые ресурсы это исключительно куски памяти. А если копируемые ресурсы что-то более сложное (ну хоть хендлы на файлы или мютексы) то простым std::swap уже не отделаешься.

Anatoly MoskovskyWhite OwlВ третьих, даже если конструктор копирования и swap() написаны правильно - конструктор все равно может упасть. И значит каждый a=b; надо оборачивать в try{}catch (или ловить исключение выше по стеку).
Нет. Не надо оборачивать ничего. Исключения ловятся там где это задумано по дизайну приложения, а не в операторе присвоения из-за неумения написать его правильно - это и есть цель которая достигается данной идиомойХорошо. Вот в этом посте 17253298 , я показал не правильный код. Покажи мне правильный код пожалуйста.
Приведи правильный код класса который никогда не сможет упасть на присвоении.

Anatoly MoskovskyЗЫ. White Owl, критика всегда уместна. Критиковать можно даже то, в чем не разбираешься. Но не надо облекать это в форму советов бывалого и тем более заниматься дартаньянизмом :)Cura te ipsum
...
Рейтинг: 0 / 0
Идиома copy-on-swap С++
    #38877802
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
White OwlAnatoly MoskovskyНаписать конструктор правильно намного проще, чем присвоение.Почему? В чем разница?
1) в конструкторе не надо очищать старые значения (что уже проще)
2) при исключении в конструкторе, автоматически вызываются деструкторы тех полей, которые инициализированы на момент исключения (что намного проще, чем руками откатывать значения в =)

White OwlТривиально это отсутствие метода. А в данном случае нетривиально то, что надо не забыть перечислить все поля. И это только в минимуме, если используемые ресурсы это исключительно куски памяти. А если копируемые ресурсы что-то более сложное (ну хоть хендлы на файлы или мютексы) то простым std::swap уже не отделаешься.
Если swap не работает на одном из полей, то в такой объект вообще нельзя присваивать.
Хотя в частности ваш пример с хендлами такого ограничения не имеет - ничего не мешает делать хендлу swap.
White OwlПриведи правильный код класса который никогда не сможет упасть на присвоении.
Господи, ну нет такой задачи не упасть. Задача - при исключении оставить объект в согласованном состоянии, чтобы после перехвата исключения где-то там наверху можно было продолжить работу с объектом.
...
Рейтинг: 0 / 0
Идиома copy-on-swap С++
    #38877809
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
White OwlА в данном случае нетривиально то, что надо не забыть перечислить все поля.
А также не забыть включить компьютер, сохранить файл перед компиляцией, и другие нетривиальные действия
...
Рейтинг: 0 / 0
Идиома copy-on-swap С++
    #38877957
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Станислав КлевцовЗдравствуйте.

Есть описание идиомы на WIKIPEDIA
https://ru.wikipedia.org/wiki/Идиома_copy-and-swap

Кто - нибудь может объяснить тоже самое, но только в двух словах и более простом языком ?


По-моему, там всё предельно понятно расписано.
Единственно, что текст немного устарел, поскольку спецификация throw уже объявлена устаревшей.
...
Рейтинг: 0 / 0
Идиома copy-on-swap С++
    #38877970
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly MoskovskyWhite OwlВо первых, никто не гарантирует что конструктор копирования написан правильно (а не точно так как я показал в примере кривого оператора присваивания).
Написать конструктор правильно намного проще, чем присвоение.



На самом деле после появления placement new конструктор стал более похож на оператор присваивания, и они почти сравнялись.
Почти -- потому что по стандарту программирс обязан после вызова placement new вызвать сам руками деструктор объекта.
Но всё равно никто не запрещает возложить на конструктор такую же семантику, как на оператор присваивания, и не вызывать деструктор.
...
Рейтинг: 0 / 0
Идиома copy-on-swap С++
    #38877980
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
White OwlAnatoly Moskovskyпропущено...

Написать конструктор правильно намного проще, чем присвоение.Почему? В чем разница?



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

Конструктор инициализирует объект, а это значит, что до этого объекта в этой памяти (*this) не было, и его не надо деинициализировать.

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

Кроме этого, конструктор копирования нельзя вызывать от самого себя (потому что бессмысленно, в принципе -- можно, но на это никто не закладывается), а оператор присваивания самому себе вполне может быть.
...
Рейтинг: 0 / 0
Идиома copy-on-swap С++
    #38878154
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZivНа самом деле после появления placement new конструктор стал более похож на оператор присваивания, и они почти сравнялись.
Почти -- потому что по стандарту программирс обязан после вызова placement new вызвать сам руками деструктор объекта.
Но всё равно никто не запрещает возложить на конструктор такую же семантику, как на оператор присваивания, и не вызывать деструктор

Введение placement new ничего не добавило принципиального. С обычным new вызов деструктора тоже вручную производится - оператором delete

И это все никакого отношения к обсуждаемому вопросу не имеет.
...
Рейтинг: 0 / 0
Идиома copy-on-swap С++
    #38878226
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly MoskovskyMasterZivНа самом деле после появления placement new конструктор стал более похож на оператор присваивания, и они почти сравнялись.
Почти -- потому что по стандарту программирс обязан после вызова placement new вызвать сам руками деструктор объекта.
Но всё равно никто не запрещает возложить на конструктор такую же семантику, как на оператор присваивания, и не вызывать деструктор

Введение placement new ничего не добавило принципиального. С обычным new вызов деструктора тоже вручную производится - оператором delete

И это все никакого отношения к обсуждаемому вопросу не имеет.

Подумай лучше ...
...
Рейтинг: 0 / 0
Идиома copy-on-swap С++
    #38878583
Фотография Станислав Клевцов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly MoskovskyСтанислав Клевцов,

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

2) Решение.
Сначала создать временный объект, копию того из которого присваивается.
Если на этом этапе произойдет исключение, то текущий объект пока еще не изменен и несогласованности нет.
Потом производится обмен полей временного объекта с полями конечного объекта путем простого побайтового копирования. Такое копирование не может выбросить исключение и оно почти не вносит дополнительных расходов.
На завершающем этапе присвоения вызовется деструктор временного объекта и очистит поля ранее принадлежавшие конечному объекту.

Таким образом данное решение позволяет всегда иметь объекты в согласованном состоянии.

Спасибо, Анатолий и White Owl ! Стало намного понятнее. Еще раз спасибо.
...
Рейтинг: 0 / 0
Идиома copy-on-swap С++
    #38879303
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Несколько мыслей.

Интересно насколько нужно много (или мало) внимания уделять вообще самому факту
возникновения подобной ситуации. Память может закончится в любой момент. Это факт.
Но сколько мы должны потратить человеко-лет чтобы весь код покрыть подобной идеомой?
Или отрефакторить.
...
Рейтинг: 0 / 0
Идиома copy-on-swap С++
    #38879326
RWolf
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mayton,

Исключение здесь необязательно связано с памятью, это может быть неудачное завершение транзакции, захват/освобождение ресурса, ошибка RPC и т.п.
...
Рейтинг: 0 / 0
Идиома copy-on-swap С++
    #38879333
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonИнтересно насколько нужно много (или мало) внимания уделять вообще самому факту
возникновения подобной ситуации. Память может закончится в любой момент. Это факт.

Исключения выкидываются далеко не только по нехватке памяти и прочих ресурсов.
При присвоении полей могут возникать и "прикладные" исключения.

maytonНо сколько мы должны потратить человеко-лет чтобы весь код покрыть подобной идеомой?
Или отрефакторить.
Так можно и не переделывать, если вас и так устраивала надежность приложения до того как вы про эту идиому узнали ))
...
Рейтинг: 0 / 0
Идиома copy-on-swap С++
    #38879396
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Столько заморочек только чтобы присваивать сами объекты вместо указателей на них... Для
кого, спрашивается смарт-указатели в стандарт ввели?..
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Идиома copy-on-swap С++
    #38879419
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov,

А если вам нужны два разных объекта, как тут смартуказатели помогут?
...
Рейтинг: 0 / 0
Идиома copy-on-swap С++
    #38879423
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly MoskovskyА если вам нужны два разных объекта, как тут смартуказатели
помогут?
Точно так же как в сабже: если создание нового объекта обломилось во время работы
копи-конструктора, указатель не присвоится и компилятор с деструктором позаботятся о
зачистке обломков.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Идиома copy-on-swap С++
    #38879490
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov,

Это все верно для ссылочной семантики.
А для семантики значений не применимо.

Например, я бы не хотел возиться со смарт-указателями на std::string. Я хочу просто работать со значениями std::string.
...
Рейтинг: 0 / 0
Идиома copy-on-swap С++
    #38879491
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
При этом естественно смарт-указатели полезны при реализации внутренностей таких классов.
...
Рейтинг: 0 / 0
Идиома copy-on-swap С++
    #38879507
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly Moskovskyя бы не хотел возиться со смарт-указателями на std::string. Я хочу
просто работать со значениями std::string.
Так std::string и есть смарт-указатель на char[], обвешанный другими методами для удобства
работы с ним.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Идиома copy-on-swap С++
    #38879513
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov,

Нет. У строки нет семантики указателей. Ее например нельзя разыменовать.
...
Рейтинг: 0 / 0
Идиома copy-on-swap С++
    #38879872
BagaBaga
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вкачу-ка я свои пять копеек. Эта идиома нужна, чтобы обеспечить т.н. "strong exception safety guarantee". Это гарантия того, что операция не портит исходные объекты. Никогда. Они всегда всегда находятся в консистентном состоянии. В случае успеха вы получаете "новое хорошее" состояние. В случае неуспеха - "старое хорошее" (но обработку исключений ни кто не отменял). И исключает случай, когда старое "уже подпортили", а "новое недособрали". Зачем это? Почему не "ручками"? Ок, вот представьте, произошло исключение, вы пытаетесь вернуть объект в "хорошее" состояние, определяете "подпорченные части" и пытаетесь восстановить их, и ваша попытка "вдруг" генетит исключение. Тогда логика восстановления будет, мягко говоря, нетривиальной.

Что интересно, ранее контейнер ака vector такую гарантию ("strong exception safety guarantee") и предоставлял. Теперь (в новом стандарте) - нет, из-за появления movable семантики.

По примеру
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
friend void swap(T& a, T& b)
{
	using std::swap;
	swap(a.f1, b.f1);
	swap(a.f2, b.f2);
	swap(a.f3, b.f3);
}


swap может выбросить исключение, так что в этом примере может получиться "частично обменявшийся" вариант ...
...
Рейтинг: 0 / 0
Идиома copy-on-swap С++
    #38879891
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BagaBagaЧто интересно, ранее контейнер ака vector такую гарантию ("strong exception safety guarantee") и предоставлял. Теперь (в новом стандарте) - нет, из-за появления movable семантики.
Как раз теперь, в стандарте С++11 swap над std объектами гарантировано не выбрасывает исключений.
А в старом этого нет, но там по факту все реализации не выбрасывали исключения.
И гарантии эти получили возможность предоставить как раз из-за появления movable.
Т.е. все строго наоборот по отношению к тому что вы сказали ))
...
Рейтинг: 0 / 0
Идиома copy-on-swap С++
    #38879901
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
По смыслу это близко к попытке ввести "транзактивность" в работу с объектами.
...
Рейтинг: 0 / 0
Идиома copy-on-swap С++
    #38880131
BagaBaga
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly MoskovskyКак раз теперь, в стандарте С++11 swap над std объектами гарантировано не выбрасывает исключений.


Это очень легко проверить. Смотрим спецификацию (для >С++11)
http://en.cppreference.com/w/cpp/algorithm/swap
Код: plaintext
1.
2.
3.
4.
5.
noexcept(

    std::is_nothrow_move_constructible<T>::value &&
    std::is_nothrow_move_assignable<T>::value
)



И видим, что swap не выбрасывает исключений тогда и __только__ __тогда__, когда не выбрасывают исключения movable-конструктор ("перемещающий" конструктор) и movable оператор присваивания ("перемещающий" оператор присваивания). Т.о., swap _НЕ_даёт гарантию отсутствия исключений.

Anatoly MoskovskyИ гарантии эти получили возможность предоставить как раз из-за появления movable.

Это утверждение я даже комментировать не буду. Movable-семантика позволила исключить дорогостоющую операцию копирования (дорогостоющую - как за счёт процессорного времени на её выполнение, так и дополнительной памяти под "лишнюю" переменную) во временный объект. Это сделало swap более быстрым на не-POD типах и менее требовательным к памяти. Но другой ценой: если раньше в процессе копирования во временную переменную происходило исключение, оно не "портило" оригинальные данные. Сейчас же появление исключения при перемещении (а не копировании, как было раньше) во временный объект __портит__ исходный объект, т.к. суть перемещения - "кража" содержимиого у одного объекта в пользу другого. Обращение "по старому имени" после выполнение move - в общем случае UB.

Anatoly MoskovskyТ.е. все строго наоборот по отношению к тому что вы сказали ))
Анатолий, вы поторопились. Всё наоборот как раз у Вас :)
...
Рейтинг: 0 / 0
Идиома copy-on-swap С++
    #38880266
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Специально для вас выделяю то что вам не понятно
Anatoly Moskovskyswap над std объектами гарантировано не выбрасывает исключений.
Потому что std классы move_constructible и move_assignable.
Таким образом, объект либо стандартный и для него swap не кидает исключения, либо объект нестандартный и вы для него либо делаете move-конструктор и move-присвоение и используете std::swap, либо пишете свой swap который не кидает исключения.
При этом, для любых классов которые вообще позволяют присвоение можно написать swap, небросающий исключения, так же как и move-конструктор и move-присвоение .
...
Рейтинг: 0 / 0
Идиома copy-on-swap С++
    #38880302
BagaBaga
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly MoskovskyСпециально для вас выделяю то что вам не понятно
Anatoly Moskovskyswap над std объектами гарантировано не выбрасывает исключений.
Потому что std классы move_constructible и move_assignable.


Анатолий, не болтайте ерундой. Простейший пример (берём любую специализацию swap):
http://en.cppreference.com/w/cpp/utility/tuple/swap2
Код: plaintext
1.
2.
noexcept specification:  
noexcept(noexcept(lhs.swap(rhs)))



И так практически в каждой специализации. НУ НЕТ ТАМ гарантии - сплошные зависимости. Потому это зависит от реализации. Сделать STL "без выбрасывания исключений" под все платформы практически невозможно. Но некоторым можно попробовать утверждать, что std::tuple не из STL ...
...
Рейтинг: 0 / 0
Идиома copy-on-swap С++
    #38880328
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BagaBagaНУ НЕТ ТАМ гарантии - сплошные зависимости
Ну не смогли вы раскрутить зависимости и увидеть в них гарантии. Ничего страшного, зайдите с другой стороны.
Попробуйте, например привести пример std класса, который можно присваивать, и одновременно в стандарте не указано что для него выполняются все требования noexcept в std::swap ( move-constructible и move-assignable).

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

BagaBagaСделать STL "без выбрасывания исключений" под все платформы практически невозможно
Я не говорил что в STL не выбрасываются исключения.
Если вам хочется на эту тему поспорить, то оставляю вас наедине с самим собой, как с автором сего утверждения.
...
Рейтинг: 0 / 0
Идиома copy-on-swap С++
    #38880395
BagaBaga
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Анатолий, вы Ваньку валяете?

- "Как раз теперь, в стандарте С++11 swap над std объектами гарантировано не выбрасывает исключений."
Именно в стандарте _ДО_ С++11 swap имел спецификафию throw(), т.е. пустую. К сожалению, это не соответствовало грубой действительности - там всё равно порождались исключения... Изменения в новом стандарте просто отразили этот факт.

Что гарантирует спецификация nothrow? Строго говоря - почти ничего. С её помощью _программист_ зуб даёт сообщает компилятору, что код не генерирует исключение. Благодаря этому компилятор может сделать некоторые оптимизации (прежде всего, на стеке). Если код заявлен как noexcept, но всё равно генерит исключение... Ок - это Ваша нога.

Далее. Исключение в swap могут бросать вызываемые там функции (о да, я КЭП). И новая спецификация это явным образом указывает. Мы уже посмотрели:
1. стандартный swap не объявлен как noexcept() - отражает зависимости от "нутра"
2. специализированный swap не объявлен как noexcept() - отражает зависимости
3. конструктор перемещения не объявлен как noexcept(). Можете заглянуть в пецификацию сами - мне лень сюда копипастить.
4. перемещающий оператор присваивания не объявлен как noexcept(). Можете заглянуть в пецификацию сами.

Разумеется, на каждый довод у Вас есть шанс попросить "копнуть глубже". Чтобы тянуть время и увиливать. Но всё куда проще.

Во-первых, можно сразу спуститься к "силикону". Что вы будете делать с аппаратным исключением? Куда "копать глубже"?

Во-вторых, вы сами признали, что сделать STL без исключений (в т.ч. для перемещающих конструкторов и операторов копирования) невозможно. Как же тогда вы собрались обеспечить noexcept swap, ведь его "безысключительность" полностью базируется на невыбрасывании исключений "нутром"?

В третьих, если стандарт что-то гарантирует, он это прописывает явным образом. Хотелось бы увидеть пункт стандарта (или его номер), который предоставляет эту гарантию , цитирую: " если все аргументы шаблонов - классы std то такие гарантии прямо следуют из стандарта."
...
Рейтинг: 0 / 0
Идиома copy-on-swap С++
    #38880522
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BagaBagaвы сами признали, что сделать STL без исключений (в т.ч. для перемещающих конструкторов и операторов копирования) невозможно
Оставляю вас. Вам видимо интересно спорить с придуманными вами утверждениями. Мне - нет.
...
Рейтинг: 0 / 0
Идиома copy-on-swap С++
    #38881084
BagaBaga
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Главное, чтобы топикстартеру польза была.
...
Рейтинг: 0 / 0
39 сообщений из 39, показаны все 2 страниц
Форумы / C++ [игнор отключен] [закрыт для гостей] / Идиома copy-on-swap С++
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]