Π§ΠΈΡ‚Π°ΠΉΡ‚Π΅ ΠΊΠ½ΠΈΠ³ΠΈ ΠΎΠ½Π»Π°ΠΉΠ½ Π½Π° Bookidrom.ru! БСсплатныС ΠΊΠ½ΠΈΠ³ΠΈ Π² ΠΎΠ΄Π½ΠΎΠΌ ΠΊΠ»ΠΈΠΊΠ΅

Π§ΠΈΡ‚Π°Ρ‚ΡŒ ΠΎΠ½Π»Π°ΠΉΠ½ Β«Π―Π·Ρ‹ΠΊ программирования C++. ΠŸΡΡ‚ΠΎΠ΅ ΠΈΠ·Π΄Π°Π½ΠΈΠ΅Β». Π‘Ρ‚Ρ€Π°Π½ΠΈΡ†Π° 185

Автор Π‘Ρ‚Π΅Π½Π»ΠΈ Π›ΠΈΠΏΠΏΠΌΠ°Π½

ΠŸΠ΅Ρ€Π²ΠΎΠΉ вСрсии Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ push_back() ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‚ΡŒ любой ΠΎΠ±ΡŠΠ΅ΠΊΡ‚, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½ ΠΊ Ρ‚ΠΈΠΏΡƒ X. Π­Ρ‚Π° вСрсия ΠΊΠΎΠΏΠΈΡ€ΡƒΠ΅Ρ‚ Π΄Π°Π½Π½Ρ‹Π΅ своСго ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π°. Π’Ρ‚ΠΎΡ€ΠΎΠΉ вСрсии ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‚ΡŒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ r-Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ Π½Π΅ являСтся константой. Π­Ρ‚Π° вСрсия Ρ‚ΠΎΡ‡Π½Π΅Π΅ ΠΈ Π»ΡƒΡ‡ΡˆΠ΅Π΅ соотвСтствуСт нСконстантным r-значСниям ΠΈ Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½Π° ΠΏΡ€ΠΈ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡Π΅ ΠΏΠΎΠ΄Π΄Π°ΡŽΡ‰Π΅Π³ΠΎΡΡ измСнСнию r-значСния (см. Ρ€Π°Π·Π΄Π΅Π» 13.6.2). Π­Ρ‚Π° вСрсия способна Π·Π°Ρ…Π²Π°Ρ‚ΠΈΡ‚ΡŒ рСсурсы своСго ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π°.

ΠžΠ±Ρ‹Ρ‡Π½ΠΎ Π½Π΅Ρ‚ Π½ΠΈΠΊΠ°ΠΊΠΎΠΉ нСобходимости ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΡΡ‚ΡŒ вСрсии Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ ΠΏΠΎΠ»ΡƒΡ‡Π°ΡŽΡ‰ΠΈΡ… const X&& ΠΈΠ»ΠΈ просто X&. ΠžΠ±Ρ‹Ρ‡Π½ΠΎ ссылку Π½Π° r-Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΏΠ΅Ρ€Π΅Π΄Π°ΡŽΡ‚ ΠΏΡ€ΠΈ нСобходимости "Π·Π°Ρ…Π²Π°Ρ‚ΠΈΡ‚ΡŒ" Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚. Для этого Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ Π½Π΅ Π΄ΠΎΠ»ΠΆΠ΅Π½ Π±Ρ‹Ρ‚ΡŒ константой. Π’ΠΎΡ‡Π½ΠΎ Ρ‚Π°ΠΊ ΠΆΠ΅ ΠΊΠΎΠΏΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° Π½Π΅ Π΄ΠΎΠ»ΠΆΠ½ΠΎ ΠΈΠ·ΠΌΠ΅Π½ΡΡ‚ΡŒ скопированный ΠΎΠ±ΡŠΠ΅ΠΊΡ‚. Π’ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π΅ ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ Π½Π΅Ρ‚ Π½ΠΈΠΊΠ°ΠΊΠΎΠΉ нСобходимости ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΡΡ‚ΡŒ Π²Π΅Ρ€ΡΠΈΡŽ, ΠΏΠΎΠ»ΡƒΡ‡Π°ΡŽΡ‰ΡƒΡŽ простой ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ X&.

Π£ ΠΏΠ΅Ρ€Π΅Π³Ρ€ΡƒΠΆΠ΅Π½Π½Ρ‹Ρ… Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ, Ρ€Π°Π·Π»ΠΈΡ‡Π°ΡŽΡ‰ΠΈΡ… ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π΅Π½ΠΈΠ΅ ΠΈ ΠΊΠΎΠΏΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π°, ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ Π΅ΡΡ‚ΡŒ ΠΎΠ΄Π½Π° вСрсия, ΠΏΠΎΠ»ΡƒΡ‡Π°ΡŽΡ‰Π°Ρ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ Ρ‚ΠΈΠΏΠ° const Π’&, ΠΈ вторая, ΠΏΠΎΠ»ΡƒΡ‡Π°ΡŽΡ‰Π°Ρ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ Ρ‚ΠΈΠΏΠ° T&&.

Π’ качСствС Π±ΠΎΠ»Π΅Π΅ ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½ΠΎΠ³ΠΎ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π° ΠΏΡ€ΠΈΠ΄Π°Π΄ΠΈΠΌ классу StrVec Π²Ρ‚ΠΎΡ€ΡƒΡŽ Π²Π΅Ρ€ΡΠΈΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ push_back():

class StrVec {

public:

 void push_back(const std::string&); // ΠΊΠΎΠΏΠΈΡ€ΡƒΠ΅Ρ‚ элСмСнт

 void push_back(std::string&&);      // ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π°Π΅Ρ‚ элСмСнт

 // Π΄Ρ€ΡƒΠ³ΠΈΠ΅ Ρ‡Π»Π΅Π½Ρ‹ ΠΊΠ°ΠΊ ΠΏΡ€Π΅ΠΆΠ΄Π΅

};

// Π½Π΅ΠΈΠ·ΠΌΠ΅Π½Π½ΠΎ с ΠΎΡ€ΠΈΠ³ΠΈΠ½Π°Π»ΡŒΠ½ΠΎΠΉ вСрсии Π² Ρ€Π°Π·Π΄Π΅Π»Π΅ 13.5

void StrVec::push_back(const string& s) {

 chk_n_alloc(); // ΡƒΠ΄ΠΎΡΡ‚ΠΎΠ²Π΅Ρ€ΠΈΡ‚ΡŒΡΡ Π² Π½Π°Π»ΠΈΡ‡ΠΈΠΈ мСста для Π΄Ρ€ΡƒΠ³ΠΎΠ³ΠΎ элСмСнта

 // ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ копию s Π² элСмСнтС, Π½Π° ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΡƒΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚ first_free

 alloc.construct(first_free++, s);

}

void StrVec::push_back(string &&s) {

 chk_n_alloc(); // пСрСсоздаСт StrVec ΠΏΡ€ΠΈ нСобходимости

 alloc.construct(first_free++, std::move(s));

}

Π­Ρ‚ΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ-Ρ‡Π»Π΅Π½Ρ‹ ΠΏΠΎΡ‡Ρ‚ΠΈ ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ‡Π½Ρ‹. Π Π°Π·Π»ΠΈΡ‡ΠΈΠ΅ Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ вСрсия ссылки Π½Π° r-Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ push_back() Π²Ρ‹Π·Ρ‹Π²Π°Π΅Ρ‚ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ move(), Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‚ΡŒ этот ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ construct(). Как ΡƒΠΆΠ΅ ΡƒΠΏΠΎΠΌΠΈΠ½Π°Π»ΠΎΡΡŒ, функция construct() ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ Ρ‚ΠΈΠΏ своСго Π²Ρ‚ΠΎΡ€ΠΎΠ³ΠΎ ΠΈ ΠΏΠΎΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΡ… Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ² для опрСдСлСния ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΠΎΠ³ΠΎ конструктора. ΠŸΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ функция move() Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ ссылку Π½Π° r-Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅, Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ construct() Π±ΡƒΠ΄Π΅Ρ‚ ΠΈΠΌΠ΅Ρ‚ΡŒ Ρ‚ΠΈΠΏ string&&. ΠŸΠΎΡΡ‚ΠΎΠΌΡƒ для создания Π½ΠΎΠ²ΠΎΠ³ΠΎ послСднСго элСмСнта Π±ΡƒΠ΄Π΅Ρ‚ использован конструктор пСрСмСщСния класса string.

Когда вызываСтся функция push_back(), Ρ‚ΠΈΠΏ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Π° опрСдСляСт, копируСтся Π»ΠΈ Π½ΠΎΠ²Ρ‹ΠΉ элСмСнт Π² ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€ ΠΈΠ»ΠΈ пСрСмСщаСтся:

StrVec vec; // пустой StrVec

string s = "some string or another";

vec.push_back(s);      // Π²Ρ‹Π·ΠΎΠ² push_back(const string&)

vec.push_back("done"); // Π²Ρ‹Π·ΠΎΠ² push_back(string&&)

Π­Ρ‚ΠΈ Π²Ρ‹Π·ΠΎΠ²Ρ‹ Ρ€Π°Π·Π»ΠΈΡ‡Π°ΡŽΡ‚ΡΡ Ρ‚Π΅ΠΌ, являСтся Π»ΠΈ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ l-Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ΠΌ (s) ΠΈΠ»ΠΈ r-Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ΠΌ (врСмСнная строка, созданная ΠΈΠ· слова "done"). Π’Ρ‹Π·ΠΎΠ²Ρ‹ Ρ€Π°ΡΠΏΠΎΠ·Π½Π°ΡŽΡ‚ΡΡ соотвСтствСнно.

Бсылки Π½Π° l-значСния, r-значСния ΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ-Ρ‡Π»Π΅Π½Ρ‹

ΠžΠ±Ρ‹Ρ‡Π½ΠΎ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ-Ρ‡Π»Π΅Π½ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° ΠΌΠΎΠΆΠ½ΠΎ Π²Ρ‹Π·Π²Π°Ρ‚ΡŒ нСзависимо ΠΎΡ‚ Ρ‚ΠΎΠ³ΠΎ, являСтся Π»ΠΈ этот ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ l- ΠΈΠ»ΠΈ r-Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ΠΌ. НапримСр:

string s1 = "a value", s2 = "another";

auto n = (s1 + s2).find('a');

Π—Π΄Π΅ΡΡŒ происходит Π²Ρ‹Π·ΠΎΠ² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ-Ρ‡Π»Π΅Π½Π° find() (см. Ρ€Π°Π·Π΄Π΅Π» 9.5.3) для r-значСния класса string, ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½Π½ΠΎΠ³ΠΎ ΠΏΡ€ΠΈ ΠΊΠΎΠ½ΠΊΠ°Ρ‚Π΅Π½Π°Ρ†ΠΈΠΈ Π΄Π²ΡƒΡ… строк. Иногда Ρ‚Π°ΠΊΠΎΠΉ способ примСнСния ΠΌΠΎΠΆΠ΅Ρ‚ ΡƒΠ΄ΠΈΠ²ΠΈΡ‚ΡŒ:

s1 + s2 = "wow!";

Π—Π΄Π΅ΡΡŒ r-Π·Π½Π°Ρ‡Π΅Π½ΠΈΡŽ присваиваСтся Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ ΠΊΠΎΠ½ΠΊΠ°Ρ‚Π΅Π½Π°Ρ†ΠΈΠΈ Π΄Π²ΡƒΡ… строк.

Π”ΠΎ Π½ΠΎΠ²ΠΎΠ³ΠΎ стандарта Π½Π΅ Π±Ρ‹Π»ΠΎ Π½ΠΈΠΊΠ°ΠΊΠΎΠ³ΠΎ способа ΠΏΡ€Π΅Π΄ΠΎΡ‚Π²Ρ€Π°Ρ‚ΠΈΡ‚ΡŒ ΠΏΠΎΠ΄ΠΎΠ±Π½ΠΎΠ΅ ΠΏΡ€ΠΈΠΌΠ΅Π½Π΅Π½ΠΈΠ΅. Для обСспСчСния совмСстимости с ΠΏΡ€Π΅ΠΆΠ½Π΅ΠΉ вСрсиСй Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅Ρ‡Π½Ρ‹Π΅ классы ΠΏΡ€ΠΎΠ΄ΠΎΠ»ΠΆΠ°ΡŽΡ‚ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Ρ‚ΡŒ присвоСниС r-Π·Π½Π°Ρ‡Π΅Π½ΠΈΡŽ; Π² собствСнных классах Ρ‚Π°ΠΊΠΎΠ΅ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΠΎΠ½Π°Π΄ΠΎΠ±ΠΈΡ‚ΡŒΡΡ ΠΏΡ€Π΅Π΄ΠΎΡ‚Π²Ρ€Π°Ρ‚ΠΈΡ‚ΡŒ. Π’ Ρ‚Π°ΠΊΠΎΠΌ случаС Π»Π΅Π²Ρ‹ΠΉ ΠΎΠΏΠ΅Ρ€Π°Π½Π΄ (Ρ‚.Π΅. ΠΎΠ±ΡŠΠ΅ΠΊΡ‚, Π½Π° ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΡƒΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ this) обязан Π±Ρ‹Ρ‚ΡŒ l-Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ΠΌ.

Бвойство l- ΠΈΠ»ΠΈ r-значСния указатСля this Π·Π°Π΄Π°ΡŽΡ‚ Ρ‚Π°ΠΊΠΈΠΌ ΠΆΠ΅ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ, ΠΊΠ°ΠΊ ΠΈ ΠΊΠΎΠ½ΡΡ‚Π°Π½Ρ‚Π½ΠΎΡΡ‚ΡŒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ-Ρ‡Π»Π΅Π½Π° (см. Ρ€Π°Π·Π΄Π΅Π» 7.1.2): помСщая ΠΊΠ²Π°Π»ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ ссылки (reference qualifier) послС списка ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ²:

class Foo {

public:

 Foo &operator=(const Foo&) &; // Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ присвоСниС Ρ‚ΠΎΠ»ΡŒΠΊΠΎ

                               // измСняСмым l-значСниям

 // Π΄Ρ€ΡƒΠ³ΠΈΠ΅ Ρ‡Π»Π΅Π½Ρ‹ класса Foo

};

Foo &Foo::operator=(const Foo &rhs) & {

 // ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ всС Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎΠ΅ для присвоСния rhs этому ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρƒ

 return *this;

}

ΠšΠ²Π°Π»ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€Ρ‹ ссылки & ΠΈΠ»ΠΈ && ΠΎΠ·Π½Π°Ρ‡Π°ΡŽΡ‚, Ρ‡Ρ‚ΠΎ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ this ΠΌΠΎΠΆΠ΅Ρ‚ ΡƒΠΊΠ°Π·Ρ‹Π²Π°Ρ‚ΡŒ Π½Π° r- ΠΈΠ»ΠΈ l-Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ соотвСтствСнно. Подобно спСцификатору const, ΠΊΠ²Π°Π»ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ ссылки ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ ΠΏΡ€ΠΈΠΌΠ΅Π½Π΅Π½ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΊ (нСстатичСской) Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ-Ρ‡Π»Π΅Π½Ρƒ ΠΈ Π΄ΠΎΠ»ΠΆΠ΅Π½ ΠΏΡ€ΠΈΡΡƒΡ‚ΡΡ‚Π²ΠΎΠ²Π°Ρ‚ΡŒ ΠΊΠ°ΠΊ Π² объявлСнии, Ρ‚Π°ΠΊ ΠΈ Π² ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ.

Π€ΡƒΠ½ΠΊΡ†ΠΈΡŽ, ΠΊΠ²Π°Π»ΠΈΡ„ΠΈΡ†ΠΈΡ€ΠΎΠ²Π°Π½Π½ΡƒΡŽ символом &, ΠΌΠΎΠΆΠ½ΠΎ ΠΏΡ€ΠΈΠΌΠ΅Π½ΠΈΡ‚ΡŒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΊ l-Π·Π½Π°Ρ‡Π΅Π½ΠΈΡŽ, Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ, ΠΊΠ²Π°Π»ΠΈΡ„ΠΈΡ†ΠΈΡ€ΠΎΠ²Π°Π½Π½ΡƒΡŽ символом &&,β€” Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΊ r-Π·Π½Π°Ρ‡Π΅Π½ΠΈΡŽ:

Foo &retFoo(); // Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ ссылку;

               // Π²Ρ‹Π·ΠΎΠ² retFoo() являСтся l-Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ΠΌ

Foo retVal();  // Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅; Π²Ρ‹Π·ΠΎΠ² retVal() - r-Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅

Foo i, j;      // i ΠΈ j - это l-значСния

i = j;         // ok: i - это l-Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅

retFoo() = j;  // ok: retFoo() Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ l-Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅

retVal() = j;  // ошибка: retVal() Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ r-Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅

i = retVal();  // ok: Π²ΠΏΠΎΠ»Π½Π΅ ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‚ΡŒ r-Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΊΠ°ΠΊ ΠΏΡ€Π°Π²Ρ‹ΠΉ

               // ΠΎΠΏΠ΅Ρ€Π°Π½Π΄ присвоСния

Ѐункция ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ ΠΊΠ²Π°Π»ΠΈΡ„ΠΈΡ†ΠΈΡ€ΠΎΠ²Π°Π½Π° ΠΈ ссылкой, ΠΈ константой. Π’ Ρ‚Π°ΠΊΠΈΡ… случаях ΠΊΠ²Π°Π»ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ ссылки Π΄ΠΎΠ»ΠΆΠ΅Π½ ΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚ΡŒ Π·Π° спСцификатором const:

class Foo {

public:

 Foo someMem() & const;    // ошибка: ΠΏΠ΅Ρ€Π²Ρ‹ΠΌ Π΄ΠΎΠ»ΠΆΠ΅Π½ Π±Ρ‹Ρ‚ΡŒ

                           // ΡΠΏΠ΅Ρ†ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ const

 Foo anotherMem() const &; // ok: спСцификатор const располоТСн ΠΏΠ΅Ρ€Π²Ρ‹ΠΌ

};

ΠŸΠ΅Ρ€Π΅Π³Ρ€ΡƒΠ·ΠΊΠ° ΠΈ ссылочныС Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ

Подобно Ρ‚ΠΎΠΌΡƒ, ΠΊΠ°ΠΊ ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠ΅Ρ€Π΅Π³Ρ€ΡƒΠ·ΠΈΡ‚ΡŒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ-Ρ‡Π»Π΅Π½ Π½Π° основании константности ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π° (см. Ρ€Π°Π·Π΄Π΅Π» 7.3.2), Π΅Π΅ ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠ΅Ρ€Π΅Π³Ρ€ΡƒΠ·ΠΈΡ‚ΡŒ Π½Π° основании ΠΊΠ²Π°Π»ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€Π° ссылки. ΠšΡ€ΠΎΠΌΠ΅ Ρ‚ΠΎΠ³ΠΎ, Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠ΅Ρ€Π΅Π³Ρ€ΡƒΠ·ΠΈΡ‚ΡŒ Π½Π° основании ΠΊΠ²Π°Π»ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€Π° ссылки ΠΈ константности. Π’ качСствС ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π° ΠΏΡ€ΠΈΠ΄Π°Π΄ΠΈΠΌ классу Foo Ρ‡Π»Π΅Π½ Ρ‚ΠΈΠΏΠ° vector ΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ sorted(), Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°ΡŽΡ‰ΡƒΡŽ копию ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° класса Foo, Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ сортируСтся Π²Π΅ΠΊΡ‚ΠΎΡ€:

class Foo {

public:

 Foo sorted() &&;      // ΠΏΡ€ΠΈΠΌΠ΅Π½ΠΈΠΌΠΎ ΠΊ измСняСмым r-значСниям

 Foo sorted() const &; // ΠΏΡ€ΠΈΠΌΠ΅Π½ΠΈΠΌΠΎ ΠΊ Π»ΡŽΠ±ΠΎΠΌΡƒ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρƒ класса Foo

 // Π΄Ρ€ΡƒΠ³ΠΈΠ΅ Ρ‡Π»Π΅Π½Ρ‹ класса Foo

private:

 vector<int> data;

};

// этот ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ - r-Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅, поэтому Π΅Π³ΠΎ ΠΌΠΎΠΆΠ½ΠΎ ΡΠΎΡ€Ρ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π½Π° мСстС

Foo Foo::sorted() && {

 sort(data.begin(), data.end());

 return *this;

}

// этот ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ Π»ΠΈΠ±ΠΎ константа, Π»ΠΈΠ±ΠΎ l-Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅;

// Ρ‚Π°ΠΊ ΠΈΠ»ΠΈ ΠΈΠ½Π°Ρ‡Π΅, Π΅Π³ΠΎ нСльзя ΡΠΎΡ€Ρ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π½Π° мСстС

Foo Foo::sorted() const & {

 Foo ret(*this);                         // создаСт копию

 sort(ret.data.begin(), ret.data.end()); // сортируСт копию

 return ret;                             // Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ копию

}

ΠŸΡ€ΠΈ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ sorted() для r-значСния Π²ΠΏΠΎΠ»Π½Π΅ бСзопасно ΡΠΎΡ€Ρ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π²Π΅ΠΊΡ‚ΠΎΡ€-Ρ‡Π»Π΅Π½ data нСпосрСдствСнно. ΠžΠ±ΡŠΠ΅ΠΊΡ‚ являСтся r-Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ΠΌ, Π° это ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ Ρƒ Π½Π΅Π³ΠΎ Π½Π΅Ρ‚ Π½ΠΈΠΊΠ°ΠΊΠΈΡ… Π΄Ρ€ΡƒΠ³ΠΈΡ… ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ΠΉ, поэтому Π΄Π°Π½Π½Ρ‹ΠΉ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ ΠΌΠΎΠΆΠ½ΠΎ ΠΈΠ·ΠΌΠ΅Π½ΠΈΡ‚ΡŒ нСпосрСдствСнно. ΠŸΡ€ΠΈ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ sorted() для константного r- ΠΈΠ»ΠΈ l-значСния ΠΈΠ·ΠΌΠ΅Π½ΠΈΡ‚ΡŒ этот ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ нСльзя, поэтому ΠΏΠ΅Ρ€Π΅Π΄ сортировкой Π²Π΅ΠΊΡ‚ΠΎΡ€-Ρ‡Π»Π΅Π½ data Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΡΠΊΠΎΠΏΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ.

Поиск ΠΏΠ΅Ρ€Π΅Π³Ρ€ΡƒΠΆΠ΅Π½Π½ΠΎΠΉ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ свойство l-Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅/r-Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°, Π²Ρ‹Π·Π²Π°Π²ΡˆΠ΅Π³ΠΎ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ sorted() для опрСдСлСния ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΠΎΠΉ вСрсии:

retVal().sorted(); // retVal() - это r-value, Π²Ρ‹Π·ΠΎΠ² Foo::sorted() &&

retFoo().sorted(); // retFoo() - это l-value,

                   // Π²Ρ‹Π·ΠΎΠ² Foo::sorted() const &

ΠŸΡ€ΠΈ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠΈ константных Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ-Ρ‡Π»Π΅Π½ΠΎΠ² ΠΌΠΎΠΆΠ½ΠΎ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚ΡŒ Π΄Π²Π΅ вСрсии, ΠΎΡ‚Π»ΠΈΡ‡Π°ΡŽΡ‰ΠΈΠ΅ΡΡ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ‚Π΅ΠΌ, Ρ‡Ρ‚ΠΎ ΠΎΠ΄Π½Π° ΠΈΠΌΠ΅Π΅Ρ‚ ΠΊΠ²Π°Π»ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ const, Π° другая Π½Π΅Ρ‚. Для ссылочной ΠΊΠ²Π°Π»ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ Π½ΠΈΡ‡Π΅Π³ΠΎ ΠΏΠΎΠ΄ΠΎΠ±Π½ΠΎΠ³ΠΎ ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ Π½Π΅Ρ‚. ΠŸΡ€ΠΈ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠΈ Π΄Π²ΡƒΡ… ΠΈΠ»ΠΈ Π±ΠΎΠ»Π΅Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ-Ρ‡Π»Π΅Π½ΠΎΠ² с Ρ‚Π΅ΠΌ ΠΆΠ΅ ΠΈΠΌΠ΅Π½Π΅ΠΌ ΠΈ Ρ‚Π΅ΠΌ ΠΆΠ΅ списком ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ² слСдуСт ΠΏΡ€Π΅Π΄ΠΎΡΡ‚Π°Π²ΠΈΡ‚ΡŒ ΠΊΠ²Π°Π»ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ ссылки для всСх ΠΈΠ»ΠΈ Π½ΠΈ для ΠΎΠ΄Π½ΠΎΠΉ ΠΈΠ· этих Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ: