?

Log in

программистское, для знающих C++ - Поклонник деепричастий [entries|archive|friends|userinfo]
Anatoly Vorobey

[ website | Website ]
[ userinfo | livejournal userinfo ]
[ archive | journal archive ]

Links
[Links:| English-language weblog ]

программистское, для знающих C++ [ноя. 4, 2012|03:39 pm]
Anatoly Vorobey
C++ Rvalue References Explained

Отличная статья об одном из новшеств стандарта C++11 - так называемых "rvalue references". Оказывается, это совсем не страшная штука, и в этой статье всего из 11 страниц автор подробно объясняет, зачем они нужны, как их использовать, и почему, если вы собираетесь использовать rvalue references вместе с exceptions в одном и том же коде, лучше сразу застрелиться.

Процитирую прекрасную таблицу ссылок на ссылки:
  • A& & becomes A&
  • A& && becomes A&
  • A&& & becomes A&
  • A&& && becomes A&&
СсылкаОтветить

Comments:
[User Picture]From: ak_47
2012-11-04 01:56 pm
Таблица напомнила мне русскую пословицу: один сын - не сын, два сына - полсына, три сына - сын.

А вообще, из всех новшеств Ц++11, эти новые ссылки самые неинтуитивные. Хотя, может это старость наступает...
(Ответить) (Thread)
[User Picture]From: trurle
2012-11-04 02:34 pm
Описание языка PL-I занимало целую полку, не думаю что существовал человек, овладевший навыками программирования на PL-I в полном объеме.

Похоже что C++ стремительно деградирует к этому состоянию. Вообще, все стремительно портится, последние времена наступают.

(Ответить) (Parent) (Thread) (Развернуть)
[User Picture]From: winpooh
2012-11-04 03:01 pm
Мне кажется, основная премудрость там состоит в двух строчках на стр.3:
Rvalue references allow a function to branch at compile time (via overload resolution)
on the condition "Am I being called on an lvalue or an rvalue?".

"Остальное - комментарий".
(Ответить) (Parent) (Thread) (Развернуть)
[User Picture]From: blacklion
2012-11-04 02:20 pm
Где-то мне мерещится тег <irony> :)
(Ответить) (Thread)
[User Picture]From: bealex
2012-11-04 02:50 pm
После пятого амперсанда затерялся.
(Ответить) (Parent) (Thread)
[User Picture]From: igorlord
2012-11-04 03:19 pm
The first page left me totally confused about what definition of l-value he will use for the remainder of the article.

Consider:
const int r = 37;

Is r an l-value or r-value? By the first definition, it is an r-value, since it cannot be on the left side of assignment. But by the second definition, it is an l-value, since it refers to a memory location, and its address can be taken.
(Ответить) (Thread)
[User Picture]From: dimrub
2012-11-04 03:35 pm
Первое определение - из С, второе - из С++. Там даже вот такая фраза есть:

In C++, this is still useful as a first, intuitive approach to lvalues and rvalues. However, C++ with its user-defined types has introduced some subtleties regarding modifiability and assignability that cause this definition to be incorrect.
(Ответить) (Parent) (Thread) (Развернуть)
From: asox
2012-11-04 04:24 pm
Is r an l-value or r-value?

r-value

Иначе код

const int r = 37;
char s[r];

был бы валиден (периодически встречаю утверждение, что так оно и есть, но, почему-то, компиляторы обычно ругаются).
(Ответить) (Parent) (Thread) (Развернуть)
[User Picture]From: amosk
2012-11-04 07:01 pm
struct S
{
    S(){}
    const S& operator=(int) const { return *this; }
};

int main()
{

    const S s;
    s = 1;
    return 0;
}


Еще вопросы есть?
(Ответить) (Parent) (Thread) (Развернуть)
From: huzhepidarasa
2012-11-04 03:44 pm
И эти люди запрещают мне ковыряться в монадах.
(Ответить) (Thread)
[User Picture]From: dimrub
2012-11-04 03:52 pm
Программист на С++ имеет все шансы состариться и уйти на пенсию, всю жизнь пользуясь rvalue references, и не зная этого (грубо говоря, если я не пишу performance intensive libraries, то они мне не нужны). У программиста на Хаскелле возможности не знать, что такое монады, нет.
(Ответить) (Parent) (Thread) (Развернуть)
[User Picture]From: francis_drake
2012-11-04 06:29 pm
Этапять!
(Ответить) (Parent) (Thread)
[User Picture]From: helvegr
2012-11-04 05:13 pm
Мне ещё вот это понравилось:

Given that rvalue references are declared using "&&", it seems reasonable to assume that the presence of "&&" in a type declaration indicates an rvalue reference. That is not the case:

Widget&& var1 = someWidget; // here, "&&" means rvalue reference
 
auto&& var2 = var1; // here, "&&" does not mean rvalue reference
 
template<typename T>
 
void f(std::vector&& param); // here, "&&" means rvalue reference
 
template<typename T>
 
void f(T&& param); // here, "&&" does not mean rvalue reference

In this article, I describe the two meanings of "&&" in type declarations, explain how to tell them apart, and introduce new terminology that makes it possible to unambiguously communicate which meaning of "&&" is intended. Distinguishing the different meanings is important, because if you think "rvalue reference" whenever you see "&&" in a type declaration, you'll misread a lot of C++11 code.


Edited at 2012-11-04 17:13 (UTC)
(Ответить) (Thread)
[User Picture]From: avva
2012-11-04 05:15 pm
Аааааа, это прекрасно, спасибо :)
(Ответить) (Parent) (Thread)
[User Picture]From: vanxant
2012-11-04 06:31 pm
О, а вот и расплата за выход С++ за пределы множества контекстно-свободных языков.
(Ответить) (Parent) (Thread) (Развернуть)
[User Picture]From: amosk
2012-11-04 07:11 pm
Какая еще расплата?
rvalue-ref были введены исключительно для оптимизации.
Если рассматривать в этом разрезе, то все вышеприведенные правила выведения типов очень логичны и интуитивно понятны.
(Ответить) (Parent) (Thread) (Развернуть)
From: huzhepidarasa
2012-11-04 08:00 pm
Даже C никогда не был контекстно-свободным. Foo(bar); — это объявление переменной или вызов функции? A C++ и подавно (goog://most+vexed+parse) хотя бы.
(Ответить) (Parent) (Thread) (Развернуть)
[User Picture]From: senecarus
2012-11-04 05:27 pm
Как хорошо, что я с этим завязал.
(Ответить) (Thread)
[User Picture]From: mstone
2012-11-04 06:28 pm
Да, очень хорошая статья. И ещё один хороший tutorial на эту тему.

Но если хочется интуитивного понимания rvalue references, надо иди сразу к Скотту Мейерсу.
(Ответить) (Thread)
[User Picture]From: vanxant
2012-11-04 06:33 pm
Да в принципе и старина Страуструп неплохо всё пояснил в своём обзоре фич С++11. Правда, в традиционном для себя стиле - каждая страница по эффекту сопоставима с таблеткой снотворного.
(Ответить) (Parent) (Thread)
[User Picture]From: amosk
2012-11-04 07:28 pm
если вы собираетесь использовать rvalue references вместе с exceptions в одном и том же коде, лучше сразу застрелиться

Что-то какая-то желтизна в этом утверждении прослеживается.
Там по ссылке указано что проблема возникает только когда move-конструкторы реализованы так что могуть выкидывать исключения.
Но это надо очень большим "талантом" обладать, чтобы так реализовать перемещение.
(Ответить) (Thread)
[User Picture]From: avva
2012-11-04 07:33 pm
Я сознательно преувеличил ради юмора ситуации, да - если хотите считать это желтизной, пожалуйста.
(Ответить) (Parent) (Thread)
From: 9000
2012-11-04 11:48 pm
Интересно, какой уровень, скажем вежливо, замороченности нужен языку, чтобы рухнуть под собственной тяжестью? C++ давно превзошёл уровень Алгола-68 и PL/I, мне кажется.

Но legacy code не даёт умереть совсем даже коболу; C++ ещё долго протянет :(
(Ответить) (Thread)
[User Picture]From: pilpilon
2012-11-05 07:56 am
вопрос, как эта замороченость размазана.
пока в плюсах писать простые вещи просто, а чуть более сложные чуть более сложно, он под своей тяжестью не рухнет, что бы там не творилась в темных углах.
(Ответить) (Parent) (Thread) (Развернуть)
[User Picture]From: ircicq
2012-11-05 08:51 am
Необходимость введения RValue refs - это следствие того что в языке все классы работают by-value.

В C# этот момент изначально продумали и есть structs (как в C++) и classes, которые by-ref. Поэтому в C# такой костыль, как RValue-refs не понадобится.
(Ответить) (Thread)