Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.75/8: Рейтинг темы: голосов - 8, средняя оценка - 4.75
1373 / 596 / 199
Регистрация: 02.08.2011
Сообщений: 2,882
1

Rvalue vector

30.05.2016, 12:41. Показов 1666. Ответов 31
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Как это?
C++
1
2
vector<int&&> v = {0,0,0};// Это не скомпилируется (Вектор, якобы, хранит rvalue)
vector<int> &&rval_vec = v; //Это не скомпилируется (Вектор, якобы, rvalue)
Встретил такое определение, как rvalue контейнер, и не понял, что это такое.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
30.05.2016, 12:41
Ответы с готовыми решениями:

Ссылка на rvalue, является ли она сама rvalue?
А верно ли, что ссылка на rvalue сама не является rvalue? Вот такой код является валидным: #include...

C++ expressions - rvalue, glvalue, prvalue, xvalue, lvalue, а также rvalue reference: что есть что?
Доброго времени суток, не понимаю до конца деление С++ - выражений (приложение 1). Lvalue вроде...

RVALUE Ссылка, error: cannot bind non-const lvalue reference of type 'String&' to an rvalue of type 'String'|
Код не компилируется ниже 17 стандарта с++ с ошибкой error: cannot bind non-const lvalue reference...

error LNK2019: ссылка на неразрешенный внешний символ "public: __thiscall Vector<int>::Vector<int>(void)" (?0?$Vector@H@@QAE@XZ) в функции _main
//Vector.h #include &lt;iostream&gt; #include &lt;Windows.h&gt; #include &lt;climits&gt; #include &lt;vector&gt;...

31
2549 / 1208 / 358
Регистрация: 30.11.2013
Сообщений: 3,826
30.05.2016, 12:45 2
daslex, я могу дико ошибаться, но по определению STL контейнеры хранят копию и следовательно, она копирует ваши нули и они вовсе не rvalue.

а 2 строка будет валидной, если первая скомпилируется и второя будет содержать std::move

P.S. Сложные у вас вечно вопрос) Где вопросики про что такое переменная - на такие я бы мог ответить, а тут снова ждать сторожил.
1
1373 / 596 / 199
Регистрация: 02.08.2011
Сообщений: 2,882
30.05.2016, 13:31  [ТС] 3
Я задам вопрос немного по-другому. Как вот в эту функцию
C++
1
2
3
4
5
6
template <typename T, typename T2>
decltype(auto) foo(T& container, T2 index)
{
 
    return container[index]; 
}
Подать временный контейнер таким образом, чтобы он в неё не передался? В смысле, что он не должен туда передаваться. rvalue невозможно связать с lvalue (если только они не являются lvalue на константные объекты).

Мне нужен такой rvalue, который не lvalue.

Добавлено через 35 минут
Вот так можно.
C++
1
foo(vector<int>{1,1,1,1,1,1,1,1,1,1}, 4) ; //rvalue отдаётся
Но мне ещё надо увидеть эффект висячей ссылки, что у этого временного вектора элемент прекращает своё существование после вызова функции.

Как связаться с такой ссылкой на элемент такого контейнера, не понимаю.
0
1550 / 875 / 179
Регистрация: 05.12.2015
Сообщений: 2,555
30.05.2016, 13:39 4
Цитата Сообщение от daslex Посмотреть сообщение
Подать временный контейнер таким образом, чтобы он в неё не передался? В смысле, что он не должен туда передаваться.
В смысле, чтобы при передаче временного контейнера была ошибка компиляции?
1
1373 / 596 / 199
Регистрация: 02.08.2011
Сообщений: 2,882
30.05.2016, 13:48  [ТС] 5
Цитата Сообщение от avgoor Посмотреть сообщение
В смысле, чтобы при передаче временного контейнера была ошибка компиляции?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
template <typename T, typename T2>
decltype(auto) foo(T& container, T2 index)
{
 
    return container[index]; 
}
 
int main(){
   foo(vector<int>{1,1,1,1,1,1,1,1,1,1}, 4) = 25 ; //rvalue отдаётся, не компилируюсь. так и надо, 
                                                               //меняю на rvalue параметры функции,
                                                               //компилируется. ОК
   /*
Здесь нужно обратиться к элементу временного вектора и словить
   эффект висячей ссылки
*/
}
0
495 / 209 / 70
Регистрация: 27.05.2016
Сообщений: 557
30.05.2016, 13:51 6
C++
1
2
3
4
5
6
template <typename T, typename T2>
decltype(auto) foo(T&& container, T2 index)
{
    static_assert(std::is_lvalue_reference<T>::value, "T must be not rvalue");
    return container[index];
}
1
1550 / 875 / 179
Регистрация: 05.12.2015
Сообщений: 2,555
30.05.2016, 14:27 7
daslex, Че то нифига не понял. Вот висячая ссылка:
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
class MyContainer
{
    int data;
public:
    MyContainer() : data(0)
    {
        std::cout << "MyContainer() " << &data << std::endl;
    }
    MyContainer(MyContainer& r) : data(r.data)
    {
        std::cout << "MyContainer(MyContainer&)" << std::endl;
    }
    MyContainer(MyContainer&& r) : data(r.data)
    {
        std::cout << "MyContainer(MyContainer&&)" << std::endl;
    }
    ~MyContainer()
    {
        std::cout << "~MyContainer()" << std::endl;
    }
 
    int& getData() { return data; }
};
 
template<class T>
decltype(auto) foo(T& cont)
{
    std::cout << "In foo() " << &cont.getData() << std::endl;
    return cont.getData();
}
 
int main()
{
    int& ref = foo(MyContainer());
    std::cout << "Will modify " << &ref << std::endl;
    ref = 42;
}
Добавлено через 19 минут
Чуть изменил, чтоб совсем похоже было:
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
class MyContainer : public std::vector<int>
{
public:
    MyContainer() : std::vector<int>(1, 1)
    {
        std::cout << "MyContainer() " << &(*this)[0] << std::endl;
    }
    MyContainer(const MyContainer& r) : std::vector<int>(r)
    {
        std::cout << "MyContainer(MyContainer&)" << std::endl;
    }
    MyContainer(MyContainer&& r) : std::vector<int>(r)
    {
        std::cout << "MyContainer(MyContainer&&)" << std::endl;
    }
    ~MyContainer()
    {
        std::cout << "~MyContainer()" << std::endl;
    }
};
 
template<class T>
decltype(auto) foo(T& cont)
{
    std::cout << "In foo() " << &cont[0] << " " << cont[0] << std::endl;
    return cont[0];
}
 
int main()
{
    int& ref = foo(MyContainer());
    std::cout << "Will modify " << &ref << " " << ref << std::endl;
    ref = 42;
    std::cout << "Now " << &ref << " " << ref << std::endl;
}
Вывод:
MyContainer() 00A72988
In foo() 00A72988 1
~MyContainer()
Will modify 00A72988 -572662307
Now 00A72988 42
1
1373 / 596 / 199
Регистрация: 02.08.2011
Сообщений: 2,882
30.05.2016, 14:53  [ТС] 8
Эффективный и современный С++.
1.3 Знакомство с decltype.

Только название функции у меня foo. Я не могу понять как поймать висячую ссылку. Что такое висячие ссылки я знаю. Я хочу её словить в конкретном примере.
Миниатюры
Rvalue vector  
0
1550 / 875 / 179
Регистрация: 05.12.2015
Сообщений: 2,555
30.05.2016, 15:03 9
daslex, Так у меня ж в выводе Все адреса совпадают, т.е. - это один объект.
В третьей строке - вывод из деструктора, т.е. объект уничтожен.
В четвертой строке видно мусор (UB, в данном случае проявилось так)
В пятой строке видно измененоое значение висячей ссылки (42). Теперь надо ловить перезапись этой памяти. Это легче сделать из первого моего примера (там висячая ссылка указывает на стек, т.е. просто вызвать несколько новых функций и убедиться что данные затрутся)
1
1373 / 596 / 199
Регистрация: 02.08.2011
Сообщений: 2,882
30.05.2016, 15:07  [ТС] 10
Пример тяжело читается...
0
1550 / 875 / 179
Регистрация: 05.12.2015
Сообщений: 2,555
30.05.2016, 15:09 11
Цитата Сообщение от daslex Посмотреть сообщение
Пример тяжело читается...
Как смог
1
1373 / 596 / 199
Регистрация: 02.08.2011
Сообщений: 2,882
30.05.2016, 15:24  [ТС] 12
Время немного нужно. Просто отклонилось от простого минималистичного немного.

Добавлено через 9 минут
Ваш пример и не компилируется в clang.

Добавлено через 42 секунды
А мне нужно понять, о чём толкует автор книги.

Добавлено через 1 минуту
я вижу xvalue, но не вижу висячести. ( в своём варианте кода)
0
99 / 70 / 13
Регистрация: 15.12.2013
Сообщений: 455
30.05.2016, 15:33 13
Цитата Сообщение от rikimaru2013 Посмотреть сообщение
daslex, я могу дико ошибаться, но по определению STL контейнеры хранят копию и следовательно, она копирует ваши нули и они вовсе не rvalue.
а 2 строка будет валидной, если первая скомпилируется и второя будет содержать std::move
P.S. Сложные у вас вечно вопрос) Где вопросики про что такое переменная - на такие я бы мог ответить, а тут снова ждать сторожил.
Действительно ошибаетесь. Первая строка не компилируется не потому, что нули не rvalue (они то как раз rvalue, а точней prvalue, которые являются rvalue), а потому что в терминологии стандарта ссылка - не объект, а посему нельзя хранить массив ссылок например, нельзя создать указатель на ссылку (но ссылку на указатель можно). Но если бы можно было создать такой вектор, как в первой строке, то вторая все равно-бы не скомпилировалась, ибо тип объекта на который ссылается ссылка и тип ссылки - разные

Добавлено через 8 минут
Цитата Сообщение от daslex Посмотреть сообщение
Я не могу понять как поймать висячую ссылку. Что такое висячие ссылки я знаю. Я хочу её словить в конкретном примере.
Тоже самое что и висячий указатель, только ссылка:
C++
1
2
3
4
5
int& get_dangling_ref()
{
    int a = 10;
    return a;
}
2
1550 / 875 / 179
Регистрация: 05.12.2015
Сообщений: 2,555
30.05.2016, 15:34 14
Цитата Сообщение от daslex Посмотреть сообщение
Ваш пример и не компилируется в clang.
Замените decltype(auto) foo(T& cont) на decltype(auto) foo(T&& cont)
http://rextester.com/live/ULEC6490
1
495 / 209 / 70
Регистрация: 27.05.2016
Сообщений: 557
30.05.2016, 15:36 15
Цитата Сообщение от daslex Посмотреть сообщение
Я не могу понять как поймать висячую ссылку
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
template <typename T, typename T2>
decltype(auto) foo(T&& container, T2 index)
{
    return container[index];
}
 
int main()
{
    std::vector<int> v{1,2,3,4};
    foo(v, 0) = 42;
    std::cout << v.front();
    auto& good_ref = foo(v, 1);
    good_ref = 84;
    std::cout << v[1];
 
    auto& bad_ref = foo(std::vector<int>{1,2,3,4}, 0);
    bad_ref = 42;
}
1
99 / 70 / 13
Регистрация: 15.12.2013
Сообщений: 455
30.05.2016, 15:40 16
Цитата Сообщение от avgoor Посмотреть сообщение
Замените decltype(auto) foo(T& cont) на decltype(auto) foo(T&& cont)
http://rextester.com/live/ULEC6490
либо на decltype(auto) foo(T const& cont)
Только return-type будет c const
1
avgoor
30.05.2016, 15:44
  #17

Не по теме:

Цитата Сообщение от ASCII Посмотреть сообщение
либо на decltype(auto) foo(T const& cont)
В данном случае, все-таки, правильнее использовать "генерализованную ссылку":
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
template<class T>
void foo(T&& t)
{
    std::cout << std::is_rvalue_reference<decltype(t)>::value << std::endl;
}
 
class A {};
 
int main()
{
    foo(A());
    A a;
    foo(a);
}
Вывод:
1
0

0
1373 / 596 / 199
Регистрация: 02.08.2011
Сообщений: 2,882
30.05.2016, 15:49  [ТС] 18
Цитата Сообщение от ASCII Посмотреть сообщение
Замените decltype(auto) foo(T& cont) на decltype(auto) foo(T&& cont)
Не пойдёт. Это получается универсальная ссылка. Которой проблема потом решается.

Это как сбежать не разобравшись.

Цитата Сообщение от ASCII Посмотреть сообщение
decltype(auto) foo(T const& cont)
Получится xvalue, так я пробовал.

notAll,
Не пойдёт. Это получается универсальная ссылка. Которой проблема потом решается.
0
99 / 70 / 13
Регистрация: 15.12.2013
Сообщений: 455
30.05.2016, 15:51 19
avgoor, Да, только будьте готовы на таком примере объяснить человеку, что такое Collapsing rule
1
1373 / 596 / 199
Регистрация: 02.08.2011
Сообщений: 2,882
30.05.2016, 15:56  [ТС] 20
Важно: Я не понимаю о чём пишет автор. Поэтому нечаянно могу и других путать.

Добавлено через 4 минуты
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>
#include <vector>
using namespace std;
 
template <typename T, typename T2>
decltype(auto) foo(T&& container, T2 index)
{
    return container[index];
}
 
int main()
{
    std::vector<int> v{1,2,3,4};
 
    int &ref = foo(vector<int>{1,2,3},2); //Ссылаюсь на элемент временного объекта, проблем нет. Должны же быть.
    cout << ref << '\n';
}
Добавлено через 43 секунды
Должна же быть проблема, коли о ней написано.
0
30.05.2016, 15:56
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
30.05.2016, 15:56
Помогаю со студенческими работами здесь

Как можно увеличить размер вектора, который является элементом вектора vector<vector<int>>arr(n, vector <int>)
Написал программу, которая создает вектор 'а' векторов 'b', вектора 'b' содержат 2 числа. Стало...

Цикл: Создайте класс Matrix на базе вектора vector<vector<int>>.
Создайте класс Matrix на базе вектора vector&lt;vector&lt;int&gt;&gt;. Определите операторную функцию ostream\&amp;...

Ошибка [Linker error] undefined reference to `Vector::Vector(int)'
Добрый день. Делал по методички, и почему-то валятся ошибки... файл lab9_main.cpp #include...

vector<Struct2{int,vector<struct1>}> или множественное наследование ...
Здравствуйте! Помогите, пожалуйста. Есть такие данные: typedef struct { int x; ...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru