Временные затраты в проекте N3290 C ++ - PullRequest
3 голосов
/ 12 сентября 2011

Точка из черновика N3290 C ++, § 12.2, 5-ая точка, строка 10.

Второй контекст - это когда ссылка связана с временным. временный, к которому привязана ссылка, или временный, который является завершенный объект подобъекта, к которому привязана ссылка сохраняется в течение всего срока действия ссылки, кроме:

Временная привязка к ссылке в новом инициализаторе (5.3.4) сохраняется до завершения полного выражения, содержащего новый инициализатор. [Пример:

struct S { int mi; const std::pair<int,int>& mp; };
S a { 1, {2,3} };
S* p = new S{ 1, {2,3} };// Creates dangling reference

- конец примера] [Примечание: это может привести к появлению висящей ссылки, и реализации рекомендуется выдавать предупреждение в такой дело. - конец примечания]

Это дополнительная точка по сравнению с C ++ 03. Но пример для меня не понятен. Не могли бы вы объяснить этот момент другим примером?

Я знаю, что такое висячие ссылки и временные объекты и что std::pair содержит два значения, возможно, разных типов данных.

1 Ответ

7 голосов
/ 12 сентября 2011

Временные значения обычно длятся только до конца выражения, в котором они были созданы:

#include <complex>


void func()
{
    std::complex<int>   a; // Real variable last until the end of scope.

    a = std::complex<int>(1,2) + std::complex<int>(3,4);
     // ^^^^^^^^^^^^^^^^^^^^^^  Creates a temporary object
     //                         This is destroyed at the end of the expression.
     // Also note the result of the addition creates a new temporary object
     // Then uses the assignment operator to change the variable 'a'
     // Both the above temporaries and the temporary returned by '+'
     // are destroyed at ';'

Если вы создаете временный объект и привязываете его к ссылке. Вы продлеваете срок его службы до той же продолжительности жизни, с которой он связан.

    std::complex<int> const& b  = std::complex<int>(5,6);
                      //           ^^^^^^^^^^^^^^^^ Temporary object
                      // ^^^^                       Bound to a reference.
                      //                            Will live as long as b lives 
                      //                            (until end of scope)

Исключением из этого правила является случай, когда временная привязка связана со ссылкой в ​​новом инициализаторе.

    S* p1 = new S{ 1, {2,3} };
    // This is the new C++11 syntax that does the `equivalent off`:

    S* p2 = new S {1, std::pair<int,int>(2,3) };
                 //   ^^^^^^^^^^^^^^^^^^^^^^^    Temporary object.
                 //                              This lives until the end of the 
                 //                              expression that belongs to the new.
                 //                              ie the temporary will be destroyed
                 //                              when we get to the ';'

Но здесь мы привязываем новый временный объект к члену

const std::pair<int,int>& mp;

Это постоянная ссылка. Но временный объект, с которым он связан, будет уничтожен в «;» в приведенном выше выражении, поэтому mp будет ссылкой на объект, который больше не существует, когда вы попытаетесь использовать его в последующих выражениях.

}
...