C++продления срока временного по константной ссылке
Я пытаюсь понять, как константные ссылки продлить срок службы временных. Я запускаю код из фрагмента в one of the answers to What are the differences between pointer variable and reference variable in C++? и получил противоречивые результаты между VC11 и g ++ 4.8. Я расширил фрагмент кода здесь:
#include <stdio.h>
struct scope_test
{
~scope_test() { printf("scope_test done!\n"); }
};
int main()
{
const scope_test& test = scope_test();
printf("in scope\n");
}
Отвечающий получил результат:
in scope
scope_test done!
Я попробовал его в VC11 и получил это:
scope_test done!
in scope
scope_test done!
Я предположил, результат был VC11 вызванный отсутствием копирования, поэтому я попытался выяснить, может ли отключение копирования elision на g ++ с fno-elide-constructors
дать тот же результат, что и VC11. (Я не думаю, что копия elision может быть переключена в VC11.) Но g ++ дает результат ответчика, независимо от установки флага.
C++ 11 Стандарт ISO/IEC 14882: 2011 (E), §12.2/4 и/5 гласит:
There are two contexts in which temporaries are destroyed at a different point than the end of the full-expression...
The second context is when a reference is bound to a temporary. The temporary to which the reference is bound or the temporary that is the complete object of a subobject to which the reference is bound persists for the lifetime of the reference except:
...
ли результат VC11 имеют ничего общего с копией элизии? Это ошибка VC11?
Ответчик утверждает:
temporaries assigned to const references live until the const reference goes out of scope
Список исключений в §12.2/5 не исключает non-const
ссылку. Что мне не хватает в стандарте?
Извлечение константы в VC11 дает тот же результат, что и VC11 с константой. Удаление const в g ++ дает error: invalid initialization of non-const reference of type ‘scope_test&’ from an rvalue of type ‘scope_test’
. Почему существует разница?
EDIT:
Я добавил копировать и перемещать конструкторами и попробовал:
#include <stdio.h>
struct scope_test
{
scope_test() { printf("regular ctor\n"); }
scope_test(const scope_test& src) { printf("copy ctor\n"); }
scope_test(scope_test&& src) { printf("move ctor\n"); }
~scope_test() { printf("scope_test done!\n"); }
};
int main()
{
const scope_test& test= scope_test();
printf("in scope\n");
}
Независимо от переключени копии элизии, г ++ дает:
regular ctor
in scope
scope_test done!
VC11 дает тот же вещь, даже если удаляется const
. Если const
удален из g ++, g ++ все еще дает error: invalid initialization of non-const reference of type ‘scope_test&’ from an rvalue of type ‘scope_test’
.
Не существует никакого копирования, поскольку есть только * один * объект. –
'const' не имеет ничего общего с продлением жизни. Любая ссылка будет сделана. Это просто, что ссылки не-const lvalue не могут связываться с rvalues, поэтому их никогда нельзя использовать таким образом. –
@KerrekSB: привязка временной ссылки 'const' может привести к созданию копии.Самый простой способ проверить, есть ли созданная копия, - это инструмент для конструктора копирования. –