Форум программистов, компьютерный форум CyberForum.ru

Ссылки на r-значения - C++

Восстановить пароль Регистрация
 
 
Ferrari F1
Заблокирован
295 / 281 / 62
Регистрация: 27.01.2015
Сообщений: 1,890
Записей в блоге: 1
Завершенные тесты: 1
04.08.2016, 09:33     Ссылки на r-значения #1
Дарова!
Знакомлюсь с r-value reference и как то трудно получается полностью вникнуть в них.
Так, например, возникает ошибка в main, но ведь ссылка может выступать как l значение
C++
1
2
3
4
5
6
7
8
9
10
int&& func()
{
    int i(1);
    return i + 2;
}
 
int main()
{
    func() = 8;
}
Или даже так, все равно то же самое
C++
1
2
3
4
5
6
7
8
9
10
int&& func()
{
    int i(1);
    return std::move(i + 2);
}
 
int main()
{
    func() = 8;
}
Добавлено через 25 минут
Или вот еще вопрос, верно ли, что в этом коде не происходит лишних копирований, т.е.
1) сперва вызывается func
2) потом в func вычисляется значение выражения i + 2
3) по завершению вычисления создается временная безымянная переменная, которая хранит результат
4) эта безымянная переменная инициализирует параметр функции move
5) move возвращает r-value ссылку
6) func возвращает r value ссылку, полученную как результат move

7) в main результат вызова func в контексте инициализации интерпритируется как r-value типа int
8) x связывается с этим r-value
C++
1
2
3
4
5
6
7
8
9
10
int&& func()
{
    int i(1);
    return std::move(i + 2);
}
 
int main()
{
    auto&& x = func();
}
Добавлено через 3 минуты
еще 1 вопрос, почему компиль выдает варнинг в этом коде
warning C4172: возвращение адреса локальной или временной переменной
C++
1
2
3
4
5
6
7
8
9
10
int&& func()
{
    int i(1);
    return i + 2; // ИЗМЕНЕНИЯ ПРОИЗОШЛИ ЗДЕСЬ
}
 
int main()
{
    auto&& x = func();
}
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
04.08.2016, 09:33     Ссылки на r-значения
Посмотрите здесь:

C++ Заменить все значения элементов матрицы нулями, значения которых меньше числа k
C++ Напишите программу, которая выдает запрос на ввод значения часов и значения минут.
operator= возврат значения и просто ссылки C++
C++ Возвращение ссылки на указатель использование её как левостороннего значения
Как лучше передавать значения в функцию? Ссылки vs указатели C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
nimazzzy
 Аватар для nimazzzy
366 / 322 / 92
Регистрация: 29.03.2016
Сообщений: 1,067
Завершенные тесты: 1
04.08.2016, 10:02     Ссылки на r-значения #2
Потому что ты возвращаешь ссылку на локальную переменную, которая уже не существует вне функции.
notAll
176 / 65 / 16
Регистрация: 27.05.2016
Сообщений: 182
Завершенные тесты: 2
04.08.2016, 10:11     Ссылки на r-значения #3
Ferrari F1, возвращать ссылки из функций можно на объекты, которые живут после ее вызова. С ссылками на rvalue можно написать как то так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
std::vector<int>&& func1(std::vector<int>& v)
{
    v.push_back(42);
    return std::move(v); //std::move скастит v с lvalue до rvalue
}
 
std::vector<int> func2()
{
    std::vector<int> v{1,2,3};
    return v; // будет перемещен
}
 
int main()
{
    std::vector<int> v{1,2,3};
    auto v2 = func1(v);
    std::cout << "v.size = " << v.size() << "\n";
    std::cout << "v2.size = " << v2.size() << "\n";
 
    auto v3 = func2();
    std::cout << "v3.size = " << v3.size() << "\n";
}
Добавлено через 3 минуты
А вот так писать не стоит, это UB:
C++
1
2
3
4
5
std::vector<int>&& func3()
{
    std::vector<int> v{1,2,3};
    return std::move(v);
}
Ferrari F1
Заблокирован
295 / 281 / 62
Регистрация: 27.01.2015
Сообщений: 1,890
Записей в блоге: 1
Завершенные тесты: 1
04.08.2016, 10:34  [ТС]     Ссылки на r-значения #4
Цитата Сообщение от nimazzzy Посмотреть сообщение
Потому что ты возвращаешь ссылку
ну так возвращается r-value ссылка, а не обычная l-value, следовательно она должна каким магическим образом (фиг знает каким) ссылаться на временное значение - в этом и есть смысл r value ссылки. А то, стирается эта переменная из стека или нет, меня это не волнует, забота об этом ложиться на плечи разработчиков компилятора.

Если переменная из стека трется, то почему в этом коде все ок?
C++
1
2
3
4
5
6
7
8
9
10
int&& func()
{
    int i(1);
    return std::move(i + 2);
}
 
int main()
{
    auto&& x = func();
}
Добавлено через 19 минут
Или вот еще вопрос, почему этот код некорректный?
C++
1
2
3
4
5
6
int main()
{
    int x = 2;
    x = std::move(x) = 3;
    system("pause");
}
nimazzzy
 Аватар для nimazzzy
366 / 322 / 92
Регистрация: 29.03.2016
Сообщений: 1,067
Завершенные тесты: 1
04.08.2016, 10:38     Ссылки на r-значения #5
Цитата Сообщение от Ferrari F1 Посмотреть сообщение
ну так возвращается r-value ссылка, а не обычная l-value, следовательно она должна каким магическим образом (фиг знает каким) ссылаться на временное значение - в этом и есть смысл r value ссылки.
Нет, смысл rvalue ссылки совсем не в этом.
Цитата Сообщение от Ferrari F1 Посмотреть сообщение
Если переменная из стека трется, то почему в этом коде все ок?
В этом коде как раз не все ок
Ferrari F1
Заблокирован
295 / 281 / 62
Регистрация: 27.01.2015
Сообщений: 1,890
Записей в блоге: 1
Завершенные тесты: 1
04.08.2016, 10:41  [ТС]     Ссылки на r-значения #6
Цитата Сообщение от notAll Посмотреть сообщение
C++
1
auto v2 = func1(v);
тут используется к-тор перемещения?

Добавлено через 1 минуту
Цитата Сообщение от nimazzzy Посмотреть сообщение
В этом коде как раз не все ок
от компилятора (msvs) не поступило ни одного варнинга/ошибки
notAll
176 / 65 / 16
Регистрация: 27.05.2016
Сообщений: 182
Завершенные тесты: 2
04.08.2016, 10:44     Ссылки на r-значения #7
Цитата Сообщение от Ferrari F1 Посмотреть сообщение
тут используется к-тор перемещения?
Да.
Ferrari F1
Заблокирован
295 / 281 / 62
Регистрация: 27.01.2015
Сообщений: 1,890
Записей в блоге: 1
Завершенные тесты: 1
04.08.2016, 10:47  [ТС]     Ссылки на r-значения #8
notAll, а возможно ли, что такое преобразуется из
C++
1
auto v2 = func1(v);
в
C++
1
auto v2(std::vector<int>(func1(v)));
?

А это в свою очередь является к-тором копирования, ведь вами была использована не прямая инициализация объекта.
DrOffset
6425 / 3799 / 880
Регистрация: 30.01.2014
Сообщений: 6,593
04.08.2016, 10:56     Ссылки на r-значения #9
Цитата Сообщение от Ferrari F1 Посмотреть сообщение
от компилятора (msvs) не поступило ни одного варнинга/ошибки
Потому что ты ее замаскировал для компилятора вызовом move. В move делается статик каст, а любой явный каст как бы говорит: "я знаю, что делаю, компилятор - не мешай мне". Вот он и не мешает.

Цитата Сообщение от Ferrari F1 Посмотреть сообщение
почему этот код некорректный?
Потому же, почему этот код некорректный:
C++
1
2
3
4
5
int foo() { return 1; }
int main()
{
    foo() = 1;
}
Стандартом запрещается изменять временные объекты встроенных типов.
Где-то тут была тема с моим участием, где про это рассказывалось.
А вот, нашел: Временные объекты встроенного типа
notAll
176 / 65 / 16
Регистрация: 27.05.2016
Сообщений: 182
Завершенные тесты: 2
04.08.2016, 11:18     Ссылки на r-значения #10
Что то я засомневался вот в этом коде:
C++
1
2
3
4
5
6
7
8
9
10
11
std::vector<int>&& func() // return xrvalue
{
    std::vector<int> v{1,2,3};
    return std::move(v);
}
 
int main()
{
    auto&& x = func();
    std::vector<int> v(x);
}
Это законно или все же UB?
Ferrari F1
Заблокирован
295 / 281 / 62
Регистрация: 27.01.2015
Сообщений: 1,890
Записей в блоге: 1
Завершенные тесты: 1
04.08.2016, 11:24  [ТС]     Ссылки на r-значения #11
notAll,
C++
1
2
3
4
5
std::vector<int> func2()
{
    std::vector<int> v{ 1,2,3 };
    return v; // будет перемещен
}
Можешь объяснить, почему v будет именно перемещен?
notAll
176 / 65 / 16
Регистрация: 27.05.2016
Сообщений: 182
Завершенные тесты: 2
04.08.2016, 11:36     Ссылки на r-значения #12
Компилятор оптимизирует. Почитай про NRVO.

Добавлено через 46 секунд
Или вот: c++11 Return value optimization or move?

Добавлено через 3 минуты
И еще: Замечание по move semantics при операторе return в C++11
DrOffset
6425 / 3799 / 880
Регистрация: 30.01.2014
Сообщений: 6,593
04.08.2016, 12:00     Ссылки на r-значения #13
Цитата Сообщение от notAll Посмотреть сообщение
Это законно или все же UB?
Это UB.

Цитата Сообщение от notAll Посмотреть сообщение
Почитай про NRVO.
C++
1
2
3
4
5
std::vector<int> func2()
{
    std::vector<int> v{ 1,2,3 };
    return v; // будет перемещен
}
NRVO тут будет, но перемещения (в терминах С++11) не будет. Это же разные механизмы так-то.
hoggy
5225 / 2116 / 403
Регистрация: 15.11.2014
Сообщений: 4,800
Завершенные тесты: 1
04.08.2016, 12:06     Ссылки на r-значения #14
Цитата Сообщение от Ferrari F1 Посмотреть сообщение
А то, стирается эта переменная из стека или нет, меня это не волнует, забота об этом ложиться на плечи разработчиков компилятора.
разработчиков компиляторов мало волнует ваше некомпетентное мнение.

Цитата Сообщение от Ferrari F1 Посмотреть сообщение
Если переменная из стека трется, то почему в этом коде все ок?
там не все ок.
там все оч и оч плохо.

Цитата Сообщение от notAll Посмотреть сообщение
Это законно или все же UB?
UB

Добавлено через 3 минуты
Цитата Сообщение от DrOffset Посмотреть сообщение
NRVO тут будет, но перемещения (в терминах С++11) не будет. Это же разные механизмы так-то.
зависет от использования.

вот так будет NRVO:

C++
1
auto v = func2();
а вот так r-value:

C++
1
2
some obj;
obj = func();
DrOffset
04.08.2016, 12:43
  #15

Не по теме:

Цитата Сообщение от hoggy Посмотреть сообщение
зависет от использования.
Да, согласен.

notAll, я там фигню написал. Конечно же при наличии move конструктора (а у вектора он есть) и отсутствии других препятствий к этому, он будет делать перемещение. Другое дело, что не всегда эффект будет сопровождаться фактичеким перемещением (сопровождаться работой move конструктора), если возможно сделать (N)RVO оптимизацию.

HelicopterK52
633 / 176 / 28
Регистрация: 27.07.2016
Сообщений: 475
Завершенные тесты: 1
04.08.2016, 19:50     Ссылки на r-значения #16
Цитата Сообщение от DrOffset Посмотреть сообщение
но перемещения (в терминах С++11) не будет.
Если убрать rvo/nrvo, то будет перемещение,
т.к. имеем xvalue в данном месте,
а значит будет перемещение:
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
//g++  4.9.3
 
#include <iostream>
 
 
 
struct Test
{
    Test() = default;
    Test(const Test&){std::cout << "Test::cctor" << std::endl;}
    Test(Test&&){std::cout << "Test::mctor" << std::endl;}
};
 
 
 
 
Test func2()
{
    Test v;
    return v; // будет перемещен
}
 
 
 
 
int main()
{
    func2();
}
http://rextester.com/BYDT55063

Добавлено через 2 минуты

Не по теме:

Цитата Сообщение от DrOffset Посмотреть сообщение
Другое дело, что не всегда эффект будет сопровождаться фактичеким перемещением
Прочитал уже после. Теперь ясно что Вы имели ввиду

DrOffset
04.08.2016, 19:52
  #17

Не по теме:

Цитата Сообщение от HelicopterK52 Посмотреть сообщение
Если убрать rvo/nrvo, то будет перемещение,
т.к. имеем xvalue в данном месте,
Я ж сказал об этом ниже.

HelicopterK52
633 / 176 / 28
Регистрация: 27.07.2016
Сообщений: 475
Завершенные тесты: 1
04.08.2016, 19:54     Ссылки на r-значения #18
Ferrari F1, что rvalue-reference, что lvalue-reference - это в первую очередь ссылка.
Возврат ссылки на локальную переменную сами знаете чем грозит. Не важно, какая именно это ссылка.
Фактически, rvalue-ссылка, это просто некая пометка что ресурсы объекта можно захапать себе, конечно, это я так по-простецки

Добавлено через 26 секунд

Не по теме:

Цитата Сообщение от DrOffset Посмотреть сообщение
Я ж сказал об этом ниже.
я ж сказал об этом ниже
Цитата Сообщение от HelicopterK52 Посмотреть сообщение
Прочитал уже после.

Ferrari F1
Заблокирован
295 / 281 / 62
Регистрация: 27.01.2015
Сообщений: 1,890
Записей в блоге: 1
Завершенные тесты: 1
04.08.2016, 19:56  [ТС]     Ссылки на r-значения #19
HelicopterK52, просто автор книги, что я щас читаю, не очень понятно объясняет материал по ним.
Читаю - будто бутерброд жую, очень тяжело курится...
Не совсем еще понимаю, что вобще из себя представляет это "перемещение" в плане ее реализации, может попробуете объяснить?

Автор не объясняет четко, когда этими ссылками можно пользоваться, а когда нельзя... в отличие от л валуе референс
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
04.08.2016, 20:02     Ссылки на r-значения
Еще ссылки по теме:

Возвращение значения в функции, ссылки, вычислить корни квадратного уравнения C++
Вывести индексы тех элементов, значения которых больше значения предыдущего C++
C++ Найти элементы массива значения которых больше значения их индексов

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

Или воспользуйтесь поиском по форуму:
HelicopterK52
633 / 176 / 28
Регистрация: 27.07.2016
Сообщений: 475
Завершенные тесты: 1
04.08.2016, 20:02     Ссылки на r-значения #20
Цитата Сообщение от Ferrari F1 Посмотреть сообщение
просто автор книги
Что за книга? Что за автор?
Цитата Сообщение от Ferrari F1 Посмотреть сообщение
может попробуете объяснить?
Думаю, попробовать можно, но надо будет подумать сначала.
Yandex
Объявления
04.08.2016, 20:02     Ссылки на r-значения
Ответ Создать тему
Опции темы

Текущее время: 09:37. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru