Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.73/37: Рейтинг темы: голосов - 37, средняя оценка - 4.73
63 / 46 / 11
Регистрация: 27.12.2017
Сообщений: 1,484

rvalue ссылки

17.12.2019, 11:36. Показов 8493. Ответов 93
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Может кто объяснить зачем нужны rvalue ссылки и как правильно работать с std::move и std::forward?
1
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
17.12.2019, 11:36
Ответы с готовыми решениями:

Зачем нужны rvalue ссылки, если есть универсальные ссылки
Читаю книгу Скотта Мэйерса... Что-то я совсем запутался с этими rvalue ссылками. Я не пойму, зачем нужны rvalue ссылки, если есть...

Ссылки от rvalue
Доброго времени суток, господа! Начал читать статью про rvalue ссылки на хабре и что-то много вопросов появилось, вот. void...

Rvalue ссылки
Литературу читаю, но доезжаю медленно(если знаете где доступно описано- напишите),тяжело болею умственной анорексией. 1.Так вот о...

93
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
18.12.2019, 12:43
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от DrOffset Посмотреть сообщение
Может ты не будешь мне мешать учить человека, а
а ты уточняй, какой именно конструктор ты имеешь ввиду.
потому что их там два.

первый - обычный конструктор копирования,
участвуют в строительстве временного объекта.

второй - референсный.
используется при строительстве результирующиего объекта.

и когда ты пишешь:
Цитата Сообщение от DrOffset Посмотреть сообщение
Почему конструктор копирования (который есть у auto_ptr) не подходит в этом случае?
сразу возникает резонный вопрос:
почему же не подходит? подходит.
и подходит, и используется.

https://rextester.com/SMMF10447
0
19501 / 10106 / 2461
Регистрация: 30.01.2014
Сообщений: 17,825
18.12.2019, 12:43
Цитата Сообщение от ReYalp Посмотреть сообщение
насколько я понял то func возвращает rvalue? а конструктор принимает на вход lvalue?
Правильно. Поэтому рассматриваться начинает следующий вариант.
А там есть еще один конструктор который выглядит так:
C++
1
2
3
4
    auto_ptr(auto_ptr_ref<_Ty> _Right) noexcept
    {   // construct by assuming pointer from _Right auto_ptr_ref
//......
    }
А теперь вот у вашего вопроса
Цитата Сообщение от ReYalp Посмотреть сообщение
откуда берется вызов operator auto_ptr_ref<_Other>() noexcept я не понимаю и почему именно auto_ptr_ref
ответ на поверхности.
0
63 / 46 / 11
Регистрация: 27.12.2017
Сообщений: 1,484
18.12.2019, 12:47  [ТС]
DrOffset, после прочтения главы мне должно стать понятно почему тут вызывается оператор ?

Добавлено через 2 минуты
DrOffset, просто слегка непонятно какую связь имеет operator auto_ptr_ref<_Other>() и rvalue ссылки ,почему вызывается именно он?
0
19501 / 10106 / 2461
Регистрация: 30.01.2014
Сообщений: 17,825
18.12.2019, 12:52
Цитата Сообщение от hoggy Посмотреть сообщение
а ты уточняй, какой именно конструктор ты имеешь ввиду.
Цитата Сообщение от hoggy Посмотреть сообщение
используется при строительстве результирующиего объекта.
Все уточнено. Процитирован участок кода, который рассматривается: инициализация объекта p1.

Добавлено через 4 минуты
Цитата Сообщение от ReYalp Посмотреть сообщение
после прочтения главы мне должно стать понятно почему тут вызывается оператор ?
После прочтения главы вам станет понятно почему тот конструктор не подошел.

Цитата Сообщение от ReYalp Посмотреть сообщение
просто слегка непонятно какую связь имеет operator auto_ptr_ref<_Other>() и rvalue ссылки
Вы сейчас находитесь в процессе нарабатывания базы знаний о предмете.

Про rvalue ссылки пока сейчас не думайте.

Цитата Сообщение от ReYalp Посмотреть сообщение
почему вызывается именно он?
Он вызывается, потому что конструктор копирования не подошел.
Потому что в классе есть другой конструктор, который принимает auto_ptr_ref<_Ty> и преобразование к auto_ptr_ref<_Other> (где _Other = _Ty) это единственный способ скомпилировать этот код.
0
63 / 46 / 11
Регистрация: 27.12.2017
Сообщений: 1,484
18.12.2019, 12:55  [ТС]
DrOffset, насколько я понял то во время
C++
1
p1 = func<int>();
срабатывает что-то типа каста и func() с rvalue кастуется в lvalue? это что-то похожее на преобразование типов при инициализации?

Добавлено через 2 минуты
Цитата Сообщение от DrOffset Посмотреть сообщение
Он вызывается, потому что конструктор копирования не подошел.
просто впервые вижу такой опертор и мне не ясно как его вообще вызывать.
0
19501 / 10106 / 2461
Регистрация: 30.01.2014
Сообщений: 17,825
18.12.2019, 12:59
Цитата Сообщение от ReYalp Посмотреть сообщение
просто впервые вижу такой опертор и мне не ясно как его вообще вызывать.
Ну так это вопрос к вашим знаниям базового С++. Если вы встречаете непонятные побочные вопросы, то нужно остановиться, разобраться в них, потом вернуться к этой теме. Я же не зря вам про неделю на разбор сказал.
0
63 / 46 / 11
Регистрация: 27.12.2017
Сообщений: 1,484
18.12.2019, 13:01  [ТС]
DrOffset, окей, Вы не подскажете как вызвать подобный оператор?
C++
1
2
3
4
5
6
7
8
9
10
template<class A>
class test {
 
public:
        template<class AA>
    operator test<AA>() {
        int a = 5;
    }
 
};
0
19501 / 10106 / 2461
Регистрация: 30.01.2014
Сообщений: 17,825
18.12.2019, 13:07
Цитата Сообщение от ReYalp Посмотреть сообщение
срабатывает что-то типа каста и func() с rvalue кастуется в lvalue?
Каст действительно есть. Оператор auto_ptr_ref<_Other> добавляет возможность неявного преобразования auto_ptr в auto_ptr_ref в подходящих для этого выражениях.

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

Добавлено через 1 минуту
Цитата Сообщение от ReYalp Посмотреть сообщение
Вы не подскажете как вызвать подобный оператор?
C++
1
2
3
    test<int> a;
    
    test<double> b = a;
Только возвращаемое значение укажите
C++
1
2
3
4
5
    template<class AA>
    operator test<AA>() {
        int a = 5;
        return test<AA>();
    }
0
63 / 46 / 11
Регистрация: 27.12.2017
Сообщений: 1,484
18.12.2019, 13:29  [ТС]
DrOffset, тоесть
C++
1
auto_ptr<int> p1 =
в auto_ptr<int> p1 = func<int>() это и есть вызов этого опертора для rvalue объекта который возвращает func?
Я слегка запутался
0
19501 / 10106 / 2461
Регистрация: 30.01.2014
Сообщений: 17,825
18.12.2019, 13:48
Лучший ответ Сообщение было отмечено ReYalp как решение

Решение

Цитата Сообщение от ReYalp Посмотреть сообщение
это и есть вызов этого опертора для rvalue объекта который возвращает func?
Да.

Он вызывается потому что есть такой конструктор, который может принять auto_ptr_ref и потому что конструктор копирования не подходит. Т.е. два критерия.

Вы уже собственно увидели одно из главных недостатков этого: это запутывает.

Первая проблема (я надеюсь вы ее увидели, потому что ничего об этом не сказали и не спросили). Когда мы делаем инициализации p1 lvalue-объектом у нас срабатывает конструктор копирования. Но при этом у нас не происходит копирования. У нас происходит перемещение владения указателем из объекта p в объект p1. Т.е. по семантике мы делаем копирование, а по факту - перемещение. Это плохо тем, что запутывает читающего код.

Вторая проблема: когда у нас копирование может быть безопасно заменено на перемещение? Правильно, когда объект временный и данные ему все равно уже не нужны. Но тут старая редакция С++ вставляет палки в колеса. У нас нет возможности так просто отобрать владение у временного объекта. К lvalue-ссылке он не привязывается, а через константную ссылку объект не изменить (ну всякие хаки с конст_кастами и mutable оставим за скобками). Поэтому рождается вот такой запутанный код.
Итак в этом коде - конструктор от аргумента auto_ptr_ref - это прото-(в археологическом смысле)-конструктор перемещения. Сам auto_ptr_ref - это прото-rvalue-ссылка.

Собственно ответ на первы вопрос:
Цитата Сообщение от ReYalp Посмотреть сообщение
Может кто объяснить зачем нужны rvalue ссылки
rvalue ссылки нужны, чтобы со стороны ядра языка узаконить возможность отбирать ресурс у временных объектов. Чтобы делать это в строго определенных случаях, общее название которым move-семантика, т.е. семантика, в противоположность семантике копирования, которая явно предполагает наличие перемещения ресурса от объекта к объекту.

Цитата Сообщение от ReYalp Посмотреть сообщение
как правильно работать с std::move
std::move - это способ явно указать, что мы собираемся отобрать владение ресурсом у lvalue. Т.е. первый пример на предыдущей странице, когда p1 инициализуется p и вопрос по поводу состояния p получает явный ответ. И в коде становится заметно, что здесь у нас семантика перемещения, а не копирования.
1
63 / 46 / 11
Регистрация: 27.12.2017
Сообщений: 1,484
18.12.2019, 14:00  [ТС]
DrOffset, у меня появилась проблема ,я не могу отобразить работу данной ситуации в более простом примере ,помогите пожалуйста ,что нужно поменять\дописать?
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
template<class A>
class test {
 
public:
    test() {};
    test(const test<A>& obj) {
    }
    template<class AA>
    operator test<AA>() {
        return test<AA>();
    }
};
 
template<class T>
test<T> func1() {
    test<T> p1;
    return p1;
}
 
 
int main()
{
    //auto_ptr<int> p1 = func<int>();
 
    test<int> a;
    test<double> b = func1<int>();
    system("pause");
}
почему в данном случае operator test срабатывает для объекта b ?

Добавлено через 2 минуты
hoggy,
Цитата Сообщение от hoggy Посмотреть сообщение
словно бык на красную тряпку.
доказано что быки не реагируют на красный как-то особенно и DrOffset просто учит меня(а в теории всех кто будет это читать) чему-то новому и тот вопрос который он мне задал был вопросом лично для меня ,так что извините если Вы не так что-то поняли
0
19501 / 10106 / 2461
Регистрация: 30.01.2014
Сообщений: 17,825
18.12.2019, 14:11
Цитата Сообщение от ReYalp Посмотреть сообщение
почему в данном случае operator test срабатывает для объекта b ?
Потому что у нас разные типы в шаблоне.
Получаем тип test<double> и тип test<int>.

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

Но, если мы напишем пользовательский оператор преобразования, то это станет возможным.
Когда мы пишем
C++
1
2
3
4
    template<class AA>
    operator test<AA>() {
        return test<AA>();
    }
То читать это надо так: "определи возможность преобразования в тип test<AA>, где AA - любой тип."
Таким образом, если вы мысленно подставите вместо AA=double, то получите test<double> - это то, что у нас с левой стороны.
Компилятор делает тоже самое. Он видит тип с левой стороны - test<double>, видит оператор преобразования в test<AA>, подставляет AA=double, и получает успешную подстановку. Код компилируется.
0
63 / 46 / 11
Регистрация: 27.12.2017
Сообщений: 1,484
18.12.2019, 14:18  [ТС]
DrOffset, у меня много вопросов 1. Если брать мой код то почему перед выховод оператора не срабатывает конструктор b? 2. Оператор возвращает значения но оно получается что никуда не приравнивается?
0
19501 / 10106 / 2461
Регистрация: 30.01.2014
Сообщений: 17,825
18.12.2019, 14:24
Цитата Сообщение от ReYalp Посмотреть сообщение
1. Если брать мой код то почему перед выховод оператора не срабатывает конструктор b?
Конструктор копирования b не срабатывает, потому что срабатывает RVO.
Вот тут я отключил это:
https://rextester.com/TJQVM58449
Можно увидеть, что делается по семантике (с++14).

Цитата Сообщение от ReYalp Посмотреть сообщение
2. Оператор возвращает значения но оно получается что никуда не приравнивается?
Из-за RVO-оптимизации, это значение сразу становится значением b.
0
63 / 46 / 11
Регистрация: 27.12.2017
Сообщений: 1,484
18.12.2019, 14:40  [ТС]
DrOffset, можете объяснить как это работает?
если убрать std::endl в операторе и в func то в операторе a будет иметь непонятное значение,если добавить << std::endl то все ок?
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
//clang 3.8.0
 
#include <iostream>
 
template<class A>
class test {
 
public:
    test() {
        std::cout << __PRETTY_FUNCTION__ << " default ctor\n";
    }
    test(const test<A>& obj) {
        std::cout << __PRETTY_FUNCTION__ << " copy ctor\n";
    }
    template<class AA>
    operator test<AA>() {
        std::cout << this->a<< std::endl;
        std::cout << __PRETTY_FUNCTION__ << "\n";
        return test<AA>();
    }
    int a = 0;
};
 
template<class T>
test<T>& func1() {
    test<T> p1;
    p1.a = 25;
    std::cout << p1.a<< std::endl;
    return p1;
}
 
 
int main()
{
    test<int> a;
    test<double> b = func1<int>();
}
0
63 / 46 / 11
Регистрация: 27.12.2017
Сообщений: 1,484
18.12.2019, 14:52  [ТС]
DrOffset, почему в таком случае не срабатывает оператор , а срабатывает конструктор?
Кликните здесь для просмотра всего текста
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
//clang 3.8.0
 
#include <iostream>
 
template<class A>
class test {
 
public:
    test() {
        std::cout << __PRETTY_FUNCTION__ << " default ctor\n";
    }
    test(const test<A>& obj) {
        std::cout << __PRETTY_FUNCTION__ << " copy ctor\n";
    }
    operator test<A>() {
        std::cout << this->a<<std::endl;
        std::cout << __PRETTY_FUNCTION__ << "\n";
        return test<A>();
    }
    int a = 0;
};
 
template<class T>
test<T> func1() {
    test<T> p1;
    return p1;
}
 
 
int main()
{
    test<int> b = func1<int>();
}
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
18.12.2019, 14:56
Цитата Сообщение от ReYalp Посмотреть сообщение
почему в таком случае не срабатывает оператор , а срабатывает конструктор?
потому что незачем.
в этом примере он вообще никак не используется.

убери его - результат не измениться.


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
#include <iostream>
 
template<class A>
class test {
 
public:
    test() {
        std::cout << __PRETTY_FUNCTION__ << " default ctor\n";
    }
    test(const test<A>& obj) {
        std::cout << __PRETTY_FUNCTION__ << " copy ctor\n";
    }
    #if 0
    operator test<A>() {
        std::cout << this->a<<std::endl;
        std::cout << __PRETTY_FUNCTION__ << "\n";
        return test<A>();
    }
    #endif
    
    int a = 0;
};
 
template<class T>
test<T> func1() {
    test<T> p1;
    return p1;
}
 
 
int main()
{
    test<int> b = func1<int>();
}
0
63 / 46 / 11
Регистрация: 27.12.2017
Сообщений: 1,484
18.12.2019, 15:04  [ТС]
hoggy, та я понимаю что он не используется ,вот и спрашиваю почему

Добавлено через 3 минуты
если взять данный пример то зачем такой оператор нужен? И как его вызвать
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
18.12.2019, 15:07
Цитата Сообщение от ReYalp Посмотреть сообщение
та я понимаю что он не используется ,вот и спрашиваю почему
потому что не нужен, Карл!
ты же не используешь форточку, если тебе в принципе не нужно открывать окошко.

Цитата Сообщение от ReYalp Посмотреть сообщение
если взять данный пример то зачем такой оператор нужен?
правильный вопрос звучит так:
зачем вообще нужен пользовательский оператор приведения?
в каких случаях, и для каких целей он используется?
1
63 / 46 / 11
Регистрация: 27.12.2017
Сообщений: 1,484
18.12.2019, 15:14  [ТС]
hoggy, вот , если взять такой пример
C++
1
2
3
4
5
struct Widget {
  Widget(int) {}
};
 
Widget w1 = 1;
то чтобы этот код(без оптимизации ) отработал правильно нужен такой оператор в int ?
Но почему это работает и в случае конструктора в Widget(int)?

Добавлено через 59 секунд
если я правильно понял то существует тогда 2 варианта преобразование типов ? С помощью конструкторов и операторов ? Или как
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
18.12.2019, 15:14

Rvalue и lvalue ссылки
Здравствуйте, что расскажите, пожалуйста что такое lvalue и rvalue ссылки и с чем их едят, где можно использовать, и чем отличается...

STL и rvalue ссылки
Привет. Помню как-то читал инфу о том, что в стандартных контейнерах rvalue работают, как lvalue. Те имеется ввиду, что имеется два...

RVALUE ссылки и операции с ними
Господа знатоки у меня вопрос следующий. Увидел недавно такую запись &quot;T&amp;&amp; a&quot;, узнал что это rvalue ссылки, вроде как разобрался что это и...

Запретить initializer-list конструктору принимать rvalue значения/ссылки
Здравствуйте! Опишу проблему из заголовка поста на примере... Допустим есть шаблонный класс с initializer-list конструктором: ...

Ссылка на rvalue, является ли она сама rvalue?
А верно ли, что ссылка на rvalue сама не является rvalue? Вот такой код является валидным: #include &lt;iostream&gt; int main() { ...


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

Или воспользуйтесь поиском по форуму:
80
Закрытая тема Создать тему
Новые блоги и статьи
Сезонность и суточность закисления почв
anaschu 04.07.2026
200 часов это все равно моловато. Есть ситуации, но нестандартные, когда смена происходит за 5 лет. Но обычно это 50 лет и более. Наверное, закисление почвы происходит сезонно в средней. . .
В чем ценность человеческого опыта в глобальном смысле?
kumehtar 03.07.2026
Возможно, ценность человека не в том, что он однажды достигает мудрости, а в том, что он становится носителем карты пути. Он знает не только истину, но и последовательность внутренних изменений,. . .
интеграция AnyLogic с самописным REST API и переход на Odoo
anaschu 03.07.2026
Успешная интеграция AnyLogic с самописным REST API и переход на промышленную Odoo WMS Сегодня проделал огромный путь от простой симуляции физических процессов до построения полноценной. . .
Поиск всех путей на ориентированном графе. Linux
dcc0 02.07.2026
Переработка старого кода из моей статьи. Через несколько переработок от PHP кода к C89 (надеюсь, 89). Но довольно запутанно получилось. Код для Linux. Но если убрать time и то, что с ним. . .
Сам себя обучал rest api
anaschu 02.07.2026
Педагогический лайфхак: Почему чистый REST API для ученика намного круче, чем готовые библиотеки Когда мы отказались от капризного JAR-файла AnyLogic и переписали код на стандартный HttpClient,. . .
rest api anylogic - выполнение модели на своём русском сайте
anaschu 02.07.2026
Как подружиться с AnyLogic Cloud API, победить провайдеров и развернуться Java-бэкенд в Docker на бесплатном хостинге: Двухдневный лог борьбы Всем привет! Хочу поделиться свежим (и довольно. . .
Где деньги лежат
kumehtar 02.07.2026
Это - японская подводная лодка I-52 (тип C2, кодовое имя Momi) вышла из Японии в марте 1944 года с миссией в оккупированную немцами Францию (Лорьян). Это была одна из «Янаги»-миссий по обмену. . .
Krabik для WoW 3.3.5a, многоязычный
AmbA 02.07.2026
Допилил бота, думаю что окончательно. Изменения: - добавлена многоязычность - добавлено снятие скриншотов - добавлено поддержание бафов хождения по воде (для жреца, дк и шамана) - и так, по. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru