O seguinte (exemplo artificial) está bom ou é um comportamento indefinido:
// undefined behavior?
const auto& c = SomeClass{};
// use c in code later
const auto& v = c.GetSomeVariable();
fonte
O seguinte (exemplo artificial) está bom ou é um comportamento indefinido:
// undefined behavior?
const auto& c = SomeClass{};
// use c in code later
const auto& v = c.GetSomeVariable();
É 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.
fonte
Sim, isso é perfeitamente seguro: a ligação a uma
const
referência estende a vida útil do temporário ao escopo dessa referência.Observe que o comportamento não é transitivo . Por exemplo, com
cc
oscilações.fonte
Isso é seguro.
fonte
É 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
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 é:fonte