Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.89/9: Рейтинг темы: голосов - 9, средняя оценка - 4.89
738 / 342 / 71
Регистрация: 10.06.2014
Сообщений: 2,358
1

Не срабатывает конструктор перемещения

08.07.2017, 16:24. Просмотров 1690. Ответов 15
Метки нет (Все метки)

Есть класс у которого удалён конструктор перемещения. Но тем не менее, при передаче обьекта данного класса в функцию по rvalue ссылке через move, ошибок не возникает несмотря на то, что конструктор перемещения удалён. Я ожидал получить ошибку компиляции, но код компилируется. Почему?

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//g++  5.4.0
 
#include <iostream>
 
struct test
{
    int *n;
    test() = default;
    test(test&&) = delete;
};
 
void bar(test&& obj)
{
    std::cout << "go";
}
 
int main()
{
   test obj;
   bar(std::move(obj));
}
http://rextester.com/JJZ76855
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
08.07.2017, 16:24
Ответы с готовыми решениями:

C++11 Конструктор перемещения
Добрый день. Решил тут познакомится с конструктором перемещения, и сразу протестировал кое-что....

Конструктор перемещения
Здравствуйте. У меня есть такой класс: class Organization { char *name; int year,...

Конструктор перемещения
Правильно написан конструктор, значения в right нужно обнулять или не нужно? class Test {...

Конструктор перемещения
Здравствуйте, пытаюсь уже некоторое время разобраться с move-семантикой. Честно говоря возникли...

15
Don't worry, be happy
16917 / 9793 / 1886
Регистрация: 27.09.2012
Сообщений: 24,270
Записей в блоге: 2
08.07.2017, 16:33 2
Цитата Сообщение от Undisputed Посмотреть сообщение
Почему?
Потому что std::move ничего не перемещает.
1
491 / 205 / 69
Регистрация: 27.05.2016
Сообщений: 545
08.07.2017, 16:54 3
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
#include <string>
#include <type_traits>
 
struct test
{
    std::string text = "Hello";
    test() = default;
    test(test&&) = delete;
};
 
template <typename T>
std::enable_if_t<std::is_same_v<T, test>> bar(T&& obj)
{
    std::cout << "go ";
}
 
int main()
{
    test obj;
    bar(std::move(obj));
    //bar(obj); // error
}
Добавлено через 7 минут
Undisputed, там в твоем примере сработало сворачивание ссылок - test&& стал просто test&. Попробуй передать в ф-цю константный объект и увидишь ошибку компиляции:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
struct test
{
    std::string text = "Hello";
    test() = default;
    test(test&&) = delete;
};
 
void bar(test&& obj)
{
    std::cout << "go ";
}
 
int main()
{
    const test obj;
    bar(std::move(obj)); // error
}
0
Don't worry, be happy
16917 / 9793 / 1886
Регистрация: 27.09.2012
Сообщений: 24,270
Записей в блоге: 2
08.07.2017, 16:56 4
Цитата Сообщение от notAll Посмотреть сообщение
там в твоем примере сработало сворачивание ссылок - test&& стал просто test&
Нет у него сворачивания в коде. А в Вашем есть.
1
738 / 342 / 71
Регистрация: 10.06.2014
Сообщений: 2,358
08.07.2017, 16:58  [ТС] 5
Croessmah,
Я понимаю, там просто каст к rvalue, а это разве при таком раскладе как выше не приводит к вызову конструктора перемещения? Как тогда переместить объект в аргумент функции?

notAll,
Увы но не понял что вы хотели сказать этим кодом... Вроде тоже самое что и у меня только в функцию добавлено enable if...
А мне нужно вызвать конструктор перемещения при передаче обьекта в функцию
0
Don't worry, be happy
16917 / 9793 / 1886
Регистрация: 27.09.2012
Сообщений: 24,270
Записей в блоге: 2
08.07.2017, 17:01 6
Цитата Сообщение от notAll Посмотреть сообщение
Попробуй передать в ф-цю константный объект и увидишь ошибку компиляции
Из-за того, что пытаемся константный объект к неконстантной ссылке скастить.
C++
1
2
3
4
5
6
7
8
9
10
void bar(const test&& obj)
{
    std::cout << "go ";
}
 
int main()
{
    const test obj;
    bar(std::move(obj)); // и нет ошибки
}
Добавлено через 1 минуту
Цитата Сообщение от Undisputed Посмотреть сообщение
Я понимаю, там просто каст к rvalue, а это разве при таком раскладе как выше не приводит к вызову конструктора перемещения? Как тогда переместить объект в аргумент функции?
Аргумент функции - ссылка. Вы когда ссылку на объект передаете, объект копируется?
Нет. С какого он будет перемещаться, если мы передаем на него ссылку?

Добавлено через 1 минуту
Цитата Сообщение от Undisputed Посмотреть сообщение
А мне нужно вызвать конструктор перемещения при передаче обьекта в функцию
C++
1
2
3
4
5
6
7
8
9
10
void bar(test obj)
{
    std::cout << "go ";
}
 
int main()
{
    test obj;
    bar(std::move(obj)); //ошибка
}
1
738 / 342 / 71
Регистрация: 10.06.2014
Сообщений: 2,358
08.07.2017, 17:02  [ТС] 7
Croessmah,
А как тогда переместить?
0
491 / 205 / 69
Регистрация: 27.05.2016
Сообщений: 545
08.07.2017, 17:13 8
Цитата Сообщение от Croessmah Посмотреть сообщение
Нет у него сворачивания в коде

Не по теме:

Да, точно.

0
738 / 342 / 71
Регистрация: 10.06.2014
Сообщений: 2,358
08.07.2017, 17:13  [ТС] 9
notAll,
Сворачивание ссылок вроде как допустимо только если есть шаблон, а у меня в примере же его нет
0
491 / 205 / 69
Регистрация: 27.05.2016
Сообщений: 545
08.07.2017, 17:16 10
Цитата Сообщение от Undisputed Посмотреть сообщение
А как тогда переместить?
Так delete убрать:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
struct test
{
    std::string text = "Hello";
    test() = default;
    //test(test&&) = delete;
};
 
void bar(test) {}
 
int main()
{
    test obj;
    bar(std::move(obj));
    std::cout << "obj: " << obj.text;
}
1
738 / 342 / 71
Регистрация: 10.06.2014
Сообщений: 2,358
08.07.2017, 17:35  [ТС] 11
notAll,
То есть компилятор увидев отсутсвие конструктора перемещения отдал предпочтение конструктору копирования?
А что если я сам хочу определить конструктор перемещения?
Вот код ниже, не смотря на наличие конструктора перемещения он не вызывается

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
//g++  5.4.0
 
#include <iostream>
 
struct test
{
    int *n;
    test() = default;
    test(test&& other) noexcept
    {
        std::cout << "moved";
        n = other.n;
        other.n = nullptr;
     }
};
 
void bar(test&& obj)
{
    std::cout << "go";
}
 
int main()
{
   test obj;
   bar(std::move(obj));
}
http://rextester.com/EQIX14397

Добавлено через 9 минут
Но если убрать rvalue от аргумента функции тогда перемещается... не понятно в чем дело
0
Don't worry, be happy
16917 / 9793 / 1886
Регистрация: 27.09.2012
Сообщений: 24,270
Записей в блоге: 2
08.07.2017, 17:38 12
Лучший ответ Сообщение было отмечено Undisputed как решение

Решение

Цитата Сообщение от Undisputed Посмотреть сообщение
Сворачивание ссылок вроде как допустимо только если есть шаблон
Не обязательно:
C++
1
2
3
4
5
    using LVR = int&;
    using RVR = int&&;
    
    using T1 = LVR&&;//T1 = int&
    using T2 = RVR&&;//T2 = int&&
Цитата Сообщение от Undisputed Посмотреть сообщение
Вот код ниже, не смотря на наличие конструктора перемещения он не вызывается
Еще раз повторяем:
Цитата Сообщение от Croessmah Посмотреть сообщение
Аргумент функции - ссылка. Вы когда ссылку на объект передаете, объект копируется?
Нет. С какого он будет перемещаться, если мы передаем на него ссылку?
C++
1
2
3
4
5
6
7
8
9
10
void bar(test obj)
{
    std::cout << "go ";
}
 
int main()
{
    test obj;
    bar(std::move(obj));
}
1
491 / 205 / 69
Регистрация: 27.05.2016
Сообщений: 545
08.07.2017, 17:48 13
Цитата Сообщение от Undisputed Посмотреть сообщение
Вот код ниже, не смотря на наличие конструктора перемещения он не вызывается
В ф-ции надо явно переместить в новый объект:
C++
1
2
3
4
void bar(test&& obj)
{
    test t(std::move(obj));
}
1
738 / 342 / 71
Регистрация: 10.06.2014
Сообщений: 2,358
08.07.2017, 17:50  [ТС] 14
Croessmah,
Эм... То есть если мы хотим переместить объект, то принимающая сторона не должна быть ссылкой(ни lvalue,ни rvalue).
Верно ли я понял?

Добавлено через 1 минуту
notAll,
Да так тоже должно сработать
0
Don't worry, be happy
16917 / 9793 / 1886
Регистрация: 27.09.2012
Сообщений: 24,270
Записей в блоге: 2
08.07.2017, 17:53 15
Undisputed, скажу иначе.
Что нужно для перемещения объекта в ссылку?
Правильно - Сталин. Сталин умер, а
значит перемещение в ссылку невозможно.
1
738 / 342 / 71
Регистрация: 10.06.2014
Сообщений: 2,358
08.07.2017, 17:59  [ТС] 16
Croessmah,
Точно... Вот я ступил!
Ссылка же она ссылается на определенный объект!
А перемещение подразумевает передачу владения из точки я А в точку Б
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
08.07.2017, 17:59

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

Конструктор перемещения
#include &lt;iostream&gt; #include &lt;memory&gt; using namespace std; class A { int x; public: ...

Не работает конструктор перемещения (C++11)
Прив. Пишу класс подобный string'гу, ну и в процессе изучаю C++. Добрался до оператора и...

Конструктор перемещения и оптимизация
Имеем тестовый код: #include &lt;iostream&gt; using namespace std; struct A { A( int v ) ...

Синтезируемый конструктор перемещения
Насколько я знаю, при определении в классе пользовательского конструктора копирования компилятор не...

Почему не вызывается конструктор перемещения?
#include &lt;iostream&gt; #include &lt;vector&gt; class Object { public: Object() { std::cout &lt;&lt;...

Конструктор перемещения по умолчанию не даёт ожидаемого эффекта
Почему не срабатывает конструктор перемещения по умолчанию? Компилятор его вроде бы добавляет, и...


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

Или воспользуйтесь поиском по форуму:
16
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2021, vBulletin Solutions, Inc.