Rozumiem, że jeśli tymczasowy jest powiązany z elementem referencyjnym na liście inicjalizacyjnej konstruktora, obiekt zostanie zniszczony podczas powrotu konstruktora.Niepożądane ostrzeżenie o powiązaniu tymczasowego z referencyjnym elementem w konstruktorze
Jednak, należy rozważyć następujący kod:
#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;
}
To wygląda doskonale ważny do mnie. Obiekt callback
będzie działać podczas całego wykonywania funkcji func
i nie należy wykonywać kopii tymczasowej dla konstruktora wrapper
.
Rzeczywiście, GCC 4.9.0 kompiluje dobrze z włączonymi wszystkimi ostrzeżeniami.
Jednak GCC 4.8.2 kompilator daje mi następujące ostrzeżenie:
$ 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} { }
^
Czy to fałszywy alarm czy mam nieporozumienie z wcieleń obiektu?
Oto moje dokładne przetestowane wersje kompilatora:
$ 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.
Wyłączenie optymalizacji daje mi błąd seg. Valgrind zwraca uwagę, że problem występuje gdzieś w pobliżu 'func (std :: function const &) :: wrapper :: call()'. –
Użycie 'w_cb {cb}' powoduje naruszenie mojego segmentu. Używanie 'w_cb (cb)' nie cierpi z powodu tego samego problemu. Testowane w g ++ 4.8.3. –
Mogłem odtworzyć błąd Valgrind z GCC 4.8.2. (Nie jest to usterka, trudna, program wyprowadza 42 i pomyślnie wychodzi zgodnie z oczekiwaniami.) Plik wykonywalny stworzony przez GCC 4.9.0 jest Valgrind-clean. Te obserwacje nie zmieniają się przy różnych poziomach optymalizacji. – 5gon12eder