Respostas:
É seguro. Const ref prolonga a vida útil temporária. O escopo será o escopo de const ref.
O tempo de vida de um objeto temporário pode ser estendido vinculando-se a uma referência de valor constante ou a uma referência de valor nominal (desde C ++ 11). Consulte a inicialização de referência para obter detalhes.
Sempre que uma referência é vinculada a um temporário ou a um subobjeto, o tempo de vida do temporário é estendido para corresponder ao tempo de vida da referência, com as seguintes exceções :
- um limite temporário para um valor de retorno de uma função em uma instrução de retorno não é estendido: é destruído imediatamente no final da expressão de retorno. Essa função sempre retorna uma referência pendente.
- um limite temporário a um membro de referência em uma lista de inicializadores de construtores persiste apenas até a saída do construtor, desde que o objeto exista. (nota: essa inicialização está incorreta a partir de DR 1696).
- existe um limite temporário para um parâmetro de referência em uma chamada de função até o final da expressão completa que contém essa chamada de função: se a função retornar uma referência que sobrevive à expressão completa, ela se tornará uma referência pendente.
- existe um limite temporário para uma referência no inicializador usado em uma nova expressão até o final da expressão completa que contém essa nova expressão, desde que o objeto inicializado. Se o objeto inicial sobreviver à expressão completa, seu membro de referência se tornará uma referência pendente.
- existe um limite temporário para uma referência em um elemento de referência de um agregado inicializado usando a sintaxe de inicialização direta (parênteses), em oposição à sintaxe de inicialização da lista (chaves) até o final da expressão completa que contém o inicializador.
struct A { int&& r; }; A a1{7}; // OK, lifetime is extended A a2(7); // well-formed, but dangling reference
Em geral, o tempo de vida de um temporário não pode ser estendido ainda mais "transmitindo-o": uma segunda referência, inicializada a partir da referência à qual o temporário estava vinculado, não afeta seu tempo de vida.
como apontou @Konrad Rudolph (e veja o último parágrafo acima):
"Se
c.GetSomeVariable()
retornar uma referência a um objeto local ou a uma referência de que ele próprio está estendendo a vida útil de algum objeto, a extensão da vida útil não será ativada"
c.GetSomeVariable()
retornar uma referência a um objeto local ou uma referência de que ele próprio está estendendo a vida útil de algum objeto, a extensão da vida útil não entra em ação.
Não deve haver problema aqui, graças à extensão da vida útil . O objeto recém-construído sobreviverá até que a referência fique fora do escopo.
Isso é seguro.
[class.temporary]/5
: Existem três contextos nos quais os temporários são destruídos em um ponto diferente do final da expressão completa . [..]
[class.temporary]/6
: O terceiro contexto é quando uma referência é vinculada a um objeto temporário. O objeto temporário ao qual a referência está vinculada ou o objeto temporário que é o objeto completo de um subobjeto ao qual a referência está vinculada persiste pelo tempo de vida da referência, se o valor de referência ao qual a referência está vinculada foi obtido através de um dos seguintes : [muitas coisas aqui]
É seguro neste caso específico. Observe, no entanto, que nem todos os temporários são seguros para capturar por referência const ... por exemplo
#include <stdio.h>
struct Foo {
int member;
Foo() : member(0) {
printf("Constructor\n");
}
~Foo() {
printf("Destructor\n");
}
const Foo& method() const {
return *this;
}
};
int main() {
{
const Foo& x = Foo{}; // safe
printf("here!\n");
}
{
const int& y = Foo{}.member; // safe too (special rule for this)
printf("here (2)!\n");
}
{
const Foo& z = Foo{}.method(); // NOT safe
printf("here (3)!\n");
}
return 0;
}
A referência obtida para z
NÃO é segura de usar, porque a instância temporária será destruída no final da expressão completa, antes de chegar à printf
instrução. A saída é:
Constructor
here!
Destructor
Constructor
here (2)!
Destructor
Constructor
Destructor
here (3)!