Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.94/34: Рейтинг темы: голосов - 34, средняя оценка - 4.94
49 / 23 / 3
Регистрация: 16.11.2011
Сообщений: 329
Записей в блоге: 5
1

особенности передачи по "&&"

16.07.2013, 01:21. Показов 6155. Ответов 13
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
я не знаю как называется передача по "&&" . я называю "по двум загогулинам."
вопрос №1: есть работающий код
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
void foo(const int&)
{    std::cout << "Hello! I'm foo(const int&)" << std::endl;  }
 
void foo(int&&)
{  std::cout << "Hello! I'm foo(int&&)" << std::endl; }
 
template <class T>
void bar(T&& t)
{     foo(t);  }
 
int main()
{   bar(42);
    return 0;
}
почему если bar принимает 42 "по двум загогулинам." то внутри него foo использует 42 как const int& и пишет соответственно "Hello! I'm foo(const int&)" (про std::forward я знаю)
вопрос №2:
если не использовать шаблон, то будет облом - почему?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>
void foo(const int&)
{    std::cout << "Hello! I'm foo(const int&)" << std::endl;  }
 
void foo(int&&)
{  std::cout << "Hello! I'm foo(int&&)" << std::endl; }
 
void bar(int&& t) // убираем template
{    foo(t); }
int main()
{    int a = 42;
    bar(a); // cannot bind 'int' lvalue to 'int&&'
    return 0;
}
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
16.07.2013, 01:21
Ответы с готовыми решениями:

Ошибка: multiple definition of `void std::swap<A>(A&amp;, A&amp;)
Хочу специализировать swap для своего класса. Получаю ошибку. Вот код:#ifndef A_H #define A_H ...

Язык C, напечатать таблицу истинности логической функции (A & B & C), где & - знаки логический операций И, НЕ
напечатать таблицу истинности логической функции (A &amp; B &amp; C), где &amp; - знаки логический операций И,...

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

В заштрихованную фигуру бросают точки с координатами x и y. Получить координаты первой точки не попавшей в эту область (фигура x*x+y*y<25&&x*x+y*y>=9&
В заштрихованную фигуру бросают точки с координатами x и y. Получить координаты первой точки не...

ostream &operator<< (ostream &output, const Array &obj) - что означает эта строка?
void Array::getArray() // вывод массива { for (int ix = 0; ix &lt; size; ix++) cout &lt;&lt;...

13
What a waste!
1608 / 1300 / 180
Регистрация: 21.04.2012
Сообщений: 2,729
16.07.2013, 01:40 2
soican, там есть правила вывода, если T - "выводимый" (deduced) тип. Тип t зависит от типа передаваемого в функцию параметра:
передали lvalue - получили lvalue ссылку (&); передали rvalue - rvalue ссылку (&&).

Добавлено через 2 минуты
Цитата Сообщение от soican Посмотреть сообщение
сли не использовать шаблон, то будет облом - почему?
Потому что a - это lvalue. Нельзя привязать lvalue к rvalue ссылке. Попробуй:
C++
1
bar(42);
или
C++
1
bar(std::move(a));
1
49 / 23 / 3
Регистрация: 16.11.2011
Сообщений: 329
Записей в блоге: 5
16.07.2013, 01:45  [ТС] 3
Цитата Сообщение от gray_fox Посмотреть сообщение
Нельзя привязать lvalue к rvalue ссылке.
это понял
Цитата Сообщение от gray_fox Посмотреть сообщение
там есть правила вывода, если T - "выводимый" (deduced) тип.
это не понял, как шаблон всё таки умудряется обойти правило "Нельзя привязать lvalue к rvalue ссылке." и в шаблоне пишут зачемто class
0
What a waste!
1608 / 1300 / 180
Регистрация: 21.04.2012
Сообщений: 2,729
16.07.2013, 01:53 4
Цитата Сообщение от soican Посмотреть сообщение
это не понял, как шаблон всё таки умудряется обойти правило "Нельзя привязать lvalue к rvalue ссылке."
Он не обходит, "у него свои". T && превращается в T & либо T && (не учитывая cv) в зависимости от типа переданного аргумента (lvalue/rvalue).

Добавлено через 5 минут
soican, можно погуглить reference collapsing rules
0
49 / 23 / 3
Регистрация: 16.11.2011
Сообщений: 329
Записей в блоге: 5
16.07.2013, 04:12  [ТС] 5
Цитата Сообщение от gray_fox Посмотреть сообщение
можно погуглить reference collapsing rules
я погуглил, пока въезжаю...но суть вопроса такая,(вопроса №1):
bar принимает 42(rvalue) по &&. а внутри него foo использует 42 как const int&, а не как int&&

Добавлено через 1 час 29 минут
оформлю свой вопрос в код:
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
#include <iostream>
void foo(const int&)
{    std::cout << "Hello! I'm foo(const int&)" << std::endl;  }
void foo(int&&)
{  std::cout << "Hello! I'm foo(int&&)" << std::endl; }
template <class T>
void bar(T&& t)
{   foo(std::move(t));
    foo(std::forward<T>(t));
    foo(t);
}
int main()
{    int i=45;
    bar(42);  bar(i);
/*результат запуска:
Hello! I'm foo(int&&)    // std::move возвращает &&
 
Hello! I'm foo(int&&)      //forward возвратит && только если не сможет возвратить &
                           // в даннном случае(bar(42)) не смог => int&&
Hello! I'm foo(const int&) // ПОЧЕМУ!!!!!!!
 
Hello! I'm foo(int&&)      // std::move возвращает &&
 
Hello! I'm foo(const int&) //forward возвратит && только если не сможет возвратить &
                           // в даннном случае(bar(i)) смог => const int&
 
Hello! I'm foo(const int&) // изначально на этапе создания ф-ции из шаблона T&& превратилось в T&
                           // т.к. int i обладает адресом и является lvalue
*/
    return 0;
}
0
В астрале
Эксперт С++
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
16.07.2013, 07:40 6
soican, Потому что t в функции это lvalue, а не rvalue.
0
49 / 23 / 3
Регистрация: 16.11.2011
Сообщений: 329
Записей в блоге: 5
16.07.2013, 11:18  [ТС] 7
Цитата Сообщение от ForEveR Посмотреть сообщение
Потому что t в функции это lvalue, а не rvalue.
странно что это и в случае "42" и в случае "int i=42"
0
Неэпический
17870 / 10635 / 2054
Регистрация: 27.09.2012
Сообщений: 26,736
Записей в блоге: 1
16.07.2013, 11:25 8
soican, что странного?
0
49 / 23 / 3
Регистрация: 16.11.2011
Сообщений: 329
Записей в блоге: 5
16.07.2013, 11:28  [ТС] 9
Цитата Сообщение от Croessmah Посмотреть сообщение
что странного?
bar принимает 42 по && а уже внутри него foo использует 42 как const int& и пишет соответственно "Hello! I'm foo(const int&)". вот я и не могу понять логику
0
В астрале
Эксперт С++
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
16.07.2013, 11:36 10
soican, Потому что переменная является lvalue. Сама по себе переменная в функции является lvalue.
0
49 / 23 / 3
Регистрация: 16.11.2011
Сообщений: 329
Записей в блоге: 5
16.07.2013, 11:41  [ТС] 11
Цитата Сообщение от ForEveR Посмотреть сообщение
Сама по себе переменная в функции является lvalue.
но у нас же есть две функции:
C++
1
2
void foo(const int&){   } 
void foo(int&&){   }
вот в bar мы запихали 42 по && а теперь в foo 42 идёт по const int&
0
В астрале
Эксперт С++
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
16.07.2013, 11:43 12
soican, t - lvalue. В функции bar(T&& t) - t в контексте функции является lvalue.
Может быть такой пример даст больше понимания
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
#include <iostream>
 
class C
{
public:
   C() {}
   C(const C&)
   {
      std::cout << "copy" << std::endl;
   }
   C(C&&)
   {
      std::cout << "move" << std::endl;
   }
};
 
class Copyable
{
public:
   Copyable(C&& c) : obj(c)
   {
   }
private:
   C obj;
};
 
class Moveable
{
public:
   Moveable(C&& c) : obj(std::move(c))
   {
   }
private:
   C obj;
};
 
int main()
{
   Copyable copy{C()};
   Moveable move{C()};
}
1
Каратель
Эксперт С++
6609 / 4028 / 401
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
16.07.2013, 12:13 13
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
#include <type_traits>
 
template <class T>
void bar(T&& t)
{   
    std::cout << std::boolalpha 
    << "is rvalue: " << std::is_rvalue_reference<decltype(t)>::value << std::endl
    << "is lvalue: " << std::is_lvalue_reference<decltype(t)>::value << std::endl;
}
int main()
{
    int i=45;
    
    bar(42);
    bar(i);
 
    return 0;
}
2
49 / 23 / 3
Регистрация: 16.11.2011
Сообщений: 329
Записей в блоге: 5
16.07.2013, 12:23  [ТС] 14
Цитата Сообщение от ForEveR Посмотреть сообщение
Может быть такой пример даст больше понимания
хороший пример
но если я напишу Moveable(C&& c) : obj(std::forward<C>(c)) вместо Moveable(C&& c) : obj(std::move(c)) будет тоже самое,а смотри, что написано:
Forward: Returns an rvalue reference to arg if arg is not an lvalue reference.
If arg is an lvalue reference, the function returns arg without modifying its type.
как всё это работает я уже понял, но вот не знаю как объяснить эту фразу

Добавлено через 6 минут
Jupiter, показательно)) вообщем юзать move и forward
0
16.07.2013, 12:23
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
16.07.2013, 12:23
Помогаю со студенческими работами здесь

Порядок вычисления: операторы «|» и «||», «&» и «&&»
В Java булевые операторы «|» и «||», и «&amp;» и «&amp;&amp;» отличаются друг от друга порядком вычеслений, а в...

Friend ostream& operator<<(ostream& stream, CArr& obj);
CArr.h #pragma once class CArr{ int* arr = nullptr; int size = 10; void swap(int *a, int...

Написать функцию swap(int& a,int& b,int& c), которая изменяет значения параметров по правилу a->b->c->a
Написал 3 функции с разной адресацией, возникает проблема с swap1 и swap. Не могу понять где...

Создать функцию с параметрами GetFunctionValue(double& a, double& b, double& c, double& x)...
Есть код что считает нужно сделать пару манипуляций что у не могу реализовать 1) создать функцию...

Выделение памяти для буффера, под std::istream& operator>>(std::istream &, String &)
Добрый день. Как осуществляется выделения памяти под перегруженный оператор ввода данных в...


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

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