Capisco che se un temporaneo è associato a un membro di riferimento nell'elenco di inizializzazione del costruttore, l'oggetto verrà distrutto al ritorno del costruttore.Avviso spuria sull'associazione temporanea al membro di riferimento nel costruttore
Tuttavia, si consideri il seguente codice:
#include <functional>
#include <iostream>
using callback_func = std::function<int(void)>;
int
func(const callback_func& callback)
{
struct wrapper
{
const callback_func& w_cb;
wrapper(const callback_func& cb) : w_cb {cb} { }
int call() { return this->w_cb() + this->w_cb(); }
};
wrapper wrp {callback};
return wrp.call();
}
int
main()
{
std::cout << func([](){ return 21; }) << std::endl;
return 0;
}
questo sembra perfettamente valido per me. L'oggetto callback
vivrà durante l'intera esecuzione della funzione func
e non dovrebbe essere eseguita alcuna copia temporanea per il costruttore wrapper
.
Infatti, GCC 4.9.0 compila bene con tutti gli avvisi abilitati.
Tuttavia, GCC 4.8.2 compilatore mi dà il seguente avviso:
$ g++ -std=c++11 -W main.cpp
main.cpp: In constructor ‘func(const callback_func&)::wrapper::wrapper(const callback_func&)’:
main.cpp:12:48: warning: a temporary bound to ‘func(const callback_func&)::wrapper::w_cb’ only persists until the constructor exits [-Wextra]
wrapper(const callback_func& cb) : w_cb {cb} { }
^
Si tratta di un falso positivo o sto equivoco le vite degli oggetti?
Qui sono le mie versioni esatte del compilatore testati:
$ g++ --version
g++ (GCC) 4.8.2
Copyright (C) 2013 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
$ g++ --version
g++ (GCC) 4.9.0 20140604 (prerelease)
Copyright (C) 2014 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Disattivare le ottimizzazioni mi dà un difetto di seg. Valgrind sottolinea che il problema è da qualche parte intorno a 'func (std :: function const &) :: wrapper :: call()'. –
L'uso di 'w_cb {cb}' comporta per me la violazione della segmentazione. L'uso di 'w_cb (cb)' non soffre dello stesso problema. Testato in g ++ 4.8.3. –
Potrei riprodurre l'errore Valgrind con GCC 4.8.2. (Non un segfault, difficile, il programma emette 42 ed esce correttamente come previsto.) L'eseguibile prodotto da GCC 4.9.0 è Valgrind-clean. Queste osservazioni non cambiano con diversi livelli di ottimizzazione. – 5gon12eder