Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.63/8: Рейтинг темы: голосов - 8, средняя оценка - 4.63
13 / 13 / 1
Регистрация: 19.10.2019
Сообщений: 607

Хочу вспомнить, в чем подвох с конструктором перемещения const D&&

06.08.2021, 20:43. Показов 1740. Ответов 24
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Есть класс:


C++
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
class D
{
public:
    D() : x(3)
    {
        std::cout<<"D()"<<std::endl;
    }
    D(const D& a)
    {
        std::cout<<"D(const D&) start ---";
        x = a.x;
        std::cout<<" end:"<< x <<std::endl;
    }
    //D& operator = (const D&) = delete;
    D(const D&& a) noexcept
    {
        //const auto ca = a;
        std::cout<<"D(const D&&) start ---";
        x = a.x;
        std::cout<<" end:"<< x <<std::endl;
    }
    D& operator = (D&&)
    {
        std::cout<<"=D(D&&)"<<std::endl; return *this;
    }
    ~D() { std::cout<<"~D()"<<std::endl; }
    int x = 6;
};
Его отличие в особенном конструкторе перемещения., который имеет мало смысла, но не могу вспомнить из-за чего это может стать источником больших проблем. Каких именно проблем тоже помню плохо. Вроде там вместо копирования идет перемещение или наоборот, но какой то большой баг.
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
06.08.2021, 20:43
Ответы с готовыми решениями:

query='SELECT * FROM resume WHERE ' & ''' & RecSet('place')& ''' & '=' & '''& s_loc &''' & - что не так?
упростил для краткости запрос. в чем ошибка? RecSet - это коннекшн. query='SELECT * FROM resume WHERE ' &amp; ''' &amp;...

Почему friend ostrem& operator <<(ostream& outs, const Rational&); - invalid function declaration?
Пытаюсь скомпилировать программу пишет friend ostrem&amp; operator &lt;&lt;(ostream&amp; outs, const Rational&amp;); - invalid function declaration. ...

error '80020009' &Icirc;&oslash;&egrave;&aacute;&ecirc;&agrave;. /lalala/profile.asp, line 28
При простейшем и сто раз работавшем скрипте, вылетает ошибка! след. содержания error '80020009' ...

24
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13184 / 6820 / 1821
Регистрация: 18.10.2014
Сообщений: 17,260
06.08.2021, 21:11
Цитата Сообщение от squareroot Посмотреть сообщение
Его отличие в особенном конструкторе перемещения., который имеет мало смысла, но не могу вспомнить из-за чего это может стать источником больших проблем.
Нет тут никакого бага, кроме бессмысленного и не нужного кода. Константная rvalue-ссылка - const D&& - это уже бессмысленно.

Цитата Сообщение от squareroot Посмотреть сообщение
но какой то большой баг
О чем речь вообще?
0
13 / 13 / 1
Регистрация: 19.10.2019
Сообщений: 607
06.08.2021, 21:26  [ТС]
TheCalligrapher, Я всетаки сумел найти ответ.
Вот: https://stackoverflow.com/ques... -reference

Добавлено через 3 минуты
т.е. от того const у нас или не const будет разный результат перегрузки конструкторов.

C++
1
2
3
4
5
6
7
8
9
class E
{
public:
    E(const D& _obj) : m_d(std::move(_obj))
    {
        std::cout<<"E()"<<std::endl;
    }
    D m_d;
};
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13184 / 6820 / 1821
Регистрация: 18.10.2014
Сообщений: 17,260
06.08.2021, 21:27
Цитата Сообщение от squareroot Посмотреть сообщение
Я всетаки сумел найти ответ.
Я в упор не увидел в той теме никакого "подвоха" или "большой бага".
0
13 / 13 / 1
Регистрация: 19.10.2019
Сообщений: 607
06.08.2021, 21:29  [ТС]
TheCalligrapher, Ну да, совсем маленький баг когда вместо одного конструктора вызывается другой, от того что машинально добавили квалификатор const конструктору перемещения.
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13184 / 6820 / 1821
Регистрация: 18.10.2014
Сообщений: 17,260
06.08.2021, 21:31
Цитата Сообщение от squareroot Посмотреть сообщение
т.е. от того const у нас или не const будет разный результат перегрузки конструкторов.
Чего? Вызываться в таком коде будет именно move constructor, независимо от того const там или не const. Никакого "разного результата перегрузки конструкторов" тут не будет.

О чем речь?

Добавлено через 1 минуту
Цитата Сообщение от squareroot Посмотреть сообщение
Ну да, совсем маленький баг когда вместо одного конструктора вызывается другой,
??? Прилинкованная вами тема ведет речь о ситуации, когда перемещающего конструктора вообще нет (или он есть). А вы нам тут рассказываете про какое-то влияние "есть const"/"нет const", которого на самом деле нет вообще и о котором по ссылке речи вообще не идет.

О чем речь?
0
13 / 13 / 1
Регистрация: 19.10.2019
Сообщений: 607
06.08.2021, 21:32  [ТС]
TheCalligrapher, А вот и нет.
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13184 / 6820 / 1821
Регистрация: 18.10.2014
Сообщений: 17,260
06.08.2021, 21:37
Цитата Сообщение от squareroot Посмотреть сообщение
А вот и нет.
Смешно...

Я полностью ответил на вопрос моим сообщением #6. Тема исчерпана.
0
13 / 13 / 1
Регистрация: 19.10.2019
Сообщений: 607
06.08.2021, 21:43  [ТС]
C++
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
32
33
34
35
36
37
38
39
40
41
class D
{
public:
    D() : x(3)
    {
        std::cout<<"D()"<<std::endl;
    }
    D(const D& a)
    {
        std::cout<<"D(const D&) start ---";
        x = a.x;
        std::cout<<" end:"<< x <<std::endl;
    }
    //D& operator = (const D&) = delete;
    D(const D&& a) noexcept // вызов конструктора перемещения
    //D(D&& a) noexcept // вызов конструктора копирования
    {
        //const auto ca = a;
        std::cout<<"D(const D&&) start ---";
        x = a.x;
        std::cout<<" end:"<< x <<std::endl;
    }
    D& operator = (D&&)
    {
        std::cout<<"=D(D&&)"<<std::endl; return *this;
    }
    ~D() { std::cout<<"~D()"<<std::endl; }
    int x = 6;
};
 
class E
{
public:
    E(const D& _obj) : m_d(std::move(_obj))
    {
        std::cout<<"E()"<<std::endl;
    }
    D m_d;
};
        D b1;
        E b3(b1);
Добавлено через 6 минут
TheCalligrapher, А что Вас за компилятор, что результат не такой как у меня ?
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13184 / 6820 / 1821
Регистрация: 18.10.2014
Сообщений: 17,260
06.08.2021, 21:44
Так в чем "подвох" еще раз? Вас удивило, что std::move сохраняет константность исходной ссылки? Ничего удивительного в этом нет. D&& невозможно привязать к константному объекту. Никакого подвоха в этом нет.
0
13 / 13 / 1
Регистрация: 19.10.2019
Сообщений: 607
06.08.2021, 21:47  [ТС]
TheCalligrapher, Я объяснил как мог. По другому не знаю как еще можно объяснить. см. моё сообщение 5.
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13184 / 6820 / 1821
Регистрация: 18.10.2014
Сообщений: 17,260
06.08.2021, 21:47
Цитата Сообщение от squareroot Посмотреть сообщение
А что Вас за компилятор, что результат не такой как у меня ?
Я тестирую

C++
1
2
    D d;
    D a = std::move(d);
и вижу, что результат не зависит от константности D&& в конструкторе.

Вы тестируете

C++
1
2
    const D d;
    D a = std::move(d);
и видите, что результат зависит от константности D&& в конструкторе.

Разумеется. Неконстантную ссылку невозможно привязать к константному объекту. Но где тут "подвох"? В чем новость? Это совершенно естественное поведение move semantics: невозможно просто так взять и переместить из константного источника. Это не "подвох", а натуральное ожидаемое поведение.
0
13 / 13 / 1
Регистрация: 19.10.2019
Сообщений: 607
06.08.2021, 21:49  [ТС]
TheCalligrapher, Я полный код теста выложил в сообщении 9
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13184 / 6820 / 1821
Регистрация: 18.10.2014
Сообщений: 17,260
06.08.2021, 22:00
Цитата Сообщение от squareroot Посмотреть сообщение
Я полный код теста выложил в сообщении 9
Это прекрасно. Но ваш "полный код теста" - это не более чем перегруженная ненужными деталями вариация

C++
1
2
3
4
5
int main()
{
  const D d;
  D a = std::move(d);
}
или, если хотите

C++
1
2
3
4
5
int main()
{
  const D d, &r = d;
  D a = std::move(r);
}
Непринципиально.

Еще раз: где "подвох"? Вы говорите о потенциале для какого-то "большого бага". Я же вижу, что наоборот: поведение move semantics совершенно естественным образом защищает вас от создания "большого бага".
0
13 / 13 / 1
Регистрация: 19.10.2019
Сообщений: 607
06.08.2021, 22:05  [ТС]
TheCalligrapher, Наверно нет никого подвоха, а мне показалось.
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13184 / 6820 / 1821
Регистрация: 18.10.2014
Сообщений: 17,260
06.08.2021, 22:16
Правила overload resolution для && и поведение std::move специально сделаны так, чтобы не позволить вам выполнить перемещение из константного объекта. Это - вполне естественно, ибо в общем случае перемещение является модифицирующей операцией.

При попытке "перемещения" из константного объекта правила overload resolution "постараются" выполнить копирование. Что тоже вполне естественно: копирование - это тоже частный случай перемещения.

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

Но это уже вопросы к вам: зачем вы вообще использовали в коде комбинацию const &&? И, если уж вы ее использовали, то почему семантика const && конструктора у вас отличается от семантики const & конструктора? И, поднимаясь выше, зачем вы вообще пытались применить std::move к константному источнику?
0
13 / 13 / 1
Регистрация: 19.10.2019
Сообщений: 607
06.08.2021, 22:22  [ТС]
зачем вы вообще использовали в коде комбинацию const &&
На вопрос зачем ответил в сообщении номер 5.
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13184 / 6820 / 1821
Регистрация: 18.10.2014
Сообщений: 17,260
06.08.2021, 22:52
Цитата Сообщение от squareroot Посмотреть сообщение
На вопрос зачем ответил в сообщении номер 5.
ОК, "машинально добавленный const".

Но ведь после "машинального добавления const", вы не сможете "машинально" написать модифицирующий конструктор перемещения, так как этот "машинально добавленный const" не даст вам этого сделать. То есть потенциал для "машинальных" проблем тут возникает только в том случае, когда семантика перемещения класса отличается от семантики копирования, но при этом все равно является немодифицирующей. Потенциально, наверное, такое возможно, но навскидку я не могу придумать хорошего осмысленного примера такой семантики перемещения.

И, опять же, чтобы нарваться на эту проблему вам нужна вторая компонента: попытка применить std::move к константному объекту в вызывающем коде, что тоже является весьма странным действием. Разве что такое может образоваться неявно, в generic коде...
0
13 / 13 / 1
Регистрация: 19.10.2019
Сообщений: 607
06.08.2021, 23:06  [ТС]
TheCalligrapher, Да, Вы были правы. В том коде нет смысла. Мне самому сначало надо вспомнить. всётаки.
Вот новый тест(упрощенный вариант рабочего кода):

C++
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
32
33
34
35
36
37
38
39
40
41
42
43
44
class D
{
public:
    D() : x(3)
    {
        std::cout<<"D()"<<std::endl;
    }
    D(const D& a)
    {
        std::cout<<"D(const D&) start ---";
        x = a.x;
        std::cout<<" end:"<< x <<std::endl;
    }
    D(D&& a) noexcept
    {
        //const auto ca = a;
        std::cout<<"D(const D&&) start ---";
        x = a.x;
        std::cout<<" end:"<< x <<std::endl;
    }
    D& operator = (D&&)
    {
        std::cout<<"=D(D&&)"<<std::endl; return *this;
    }
    ~D() { std::cout<<"~D()"<<std::endl; }
    int x = 6;
};
 
class E
{
public:
    E() {std::cout<<"E()"<<std::endl;}
    //E(const E&& _obj) : m_d(std::move(_obj.m_d))
    E(E&& _obj) : m_d(std::move(_obj.m_d))
    {
        std::cout<<"E(&&)"<<std::endl;
    }
    E(const E& _obj) : m_d(_obj.m_d)
    {
        std::cout<<"E(const &)"<<std::endl;
    }
    ~E() { std::cout<<"~E()"<<std::endl; }
    D m_d;
};
Опечатка была у меня в классе E, а не D.

Добавлено через 13 минут
Для запуска:

C++
1
2
        E e1;
        E d3(std::move(e1));
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13184 / 6820 / 1821
Регистрация: 18.10.2014
Сообщений: 17,260
07.08.2021, 08:02
Цитата Сообщение от squareroot Посмотреть сообщение
Для запуска:
Но я по-прежнему не понимаю, опасность какой "большой ошибки" должен продемонстрировать этот пример. Все, что здесь происходит, по-прежнему подчиняется все тому же естественному правилу: нельзя сделать модифицирующее перемещение из константного объекта.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
07.08.2021, 08:02
Помогаю со студенческими работами здесь

Помогите найти драйвера для pci\ven_8086&DEV_266E&SUBSYS_A002145&REV_05\3&13C0B0C5&0&F2
pci\ven_8086&amp;DEV_266E&amp;SUBSYS_A002145&amp;REV_05\3&amp;13C0B0C5&amp;0&amp;F2 Мультимедиа аудиоконтроллер помогите плз найти...

Мультимедиа контролер PCI\VEN_14F1&DEV_8800&SUBSYS_EA3D14F1&REV_05\4&25700A26&0&3020
Помогите пожалуйста найти драйвер на мультимедиа видеоконтролер ...

немогу найти драйвера на PCI\VEN_1039&DEV_7012&SUBSYS_810D1043&REV_A0\3&61AAA01&0&17
Мультимедиа аудиоконтроллер PCI\VEN_1039&amp;DEV_7012&amp;SUBSYS_810D1043&amp;REV_A0\3&amp;61AAA01&amp;0&amp;17

Нужен драйвера, код PCI\VEN_1039&DEV_7012&SUBSYS_0C98105B&REV_A0\3&B1BFB68&0&17
всем привет !! уменя нет звука нужен драйвер код PCI\VEN_1039&amp;DEV_7012&amp;SUBSYS_0C98105B&amp;REV_A0\3&amp;B1BFB68&amp;0&amp;17 скачал прогу их много ...

Драйвера на PCI\VEN_10B7&DEV_1700&SUBSYS_80EB1043&REV_12\4&2E98101C&0&28 F0
помогите плиз - вот ID: PCI\VEN_10B7&amp;DEV_1700&amp;SUBSYS_80EB1043&amp;REV_12\4&amp;2E98101C&amp;0&amp;28F0 Заранее...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Очистка реквизитов документа при копировании
Maks 09.04.2026
Алгоритм из решения ниже применим как для типовых, так и для нетиповых документов на самых различных конфигурациях. Задача: при копировании документа очищать определенные реквизиты и табличную. . .
модель ЗдравоСохранения 8. Подготовка к разному выполнению заданий
anaschu 08.04.2026
https:/ / github. com/ shumilovas/ med2. git main ветка * содержимое блока дэлэй из старой модели теперь внутри зайца новой модели 8ATzM_2aurI
Блокировка документа от изменений, если он открыт у другого пользователя
Maks 08.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа, разработанного в конфигурации КА2. Задача: запретить редактирование документа, если он открыт у другого пользователя. / / . . .
Система безопасности+живучести для сервера-слоя интернета (сети). Двойная привязка.
Hrethgir 08.04.2026
Далее были размышления о системе безопасности. Сообщения с наклонным текстом - мои. А как нам будет можно проверить, что ссылка наша, а не подделана хулиганами, которая выбросит на другую ветку и. . .
Модель ЗдрввоСохранения 7: больше работников, больше ресурсов.
anaschu 08.04.2026
работников и заданий может быть сколько угодно, но настроено всё так, что используется пока что только 20% kYBz3eJf3jQ
Дальние перспективы сервера - слоя сети с космологическим дизайном интефейса карты и логики.
Hrethgir 07.04.2026
Дальнейшее ближайшее планирование вывело к размышлениям над дальними перспективами. И вот тут может быть даже будут нужны оценки специалистов, так как в дальних перспективах всё может очень сильно. . .
Горе от ума
kumehtar 07.04.2026
Эта мне ментальная установка, что вот прямо сейчас, мол, мне для полного счастья не хватает (нужное вписать), и когда я этого достигну - тогда и полный кайф. Одна из самых сильных ловушек на пути. . . .
Использование значений реквизитов справочника в документе, с определенными условиями и правами
Maks 07.04.2026
1. Контроль срока действия договора Алгоритм из решения ниже реализован на примере нетипового документа "ЗаявкаНаРаботу", разработанного в конфигурации КА2. Задача: уведомлять пользователя, если. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru