Kötü şeyler ve gerçekleşeceğini olabilir.
struct my_functor {
void operator()(int x) { sum += x; }
int sum = 0;
}
std::vector<int> v{1,2,3};
const auto& s = my_for_each(v.begin(), v.end(), my_functor{});
auto sum = s.sum;
Bu kod tanımlanmamış bir davranış. Geçici bir my_functor
örneği oluşturursunuz. Bu, işlev çağrısı my_for_each
girdiğinde, şimdiki kullanım ömrünü uzatarak, geçerli referansa bağlanır. İşlev çıktığı zaman, geçici olarak bir rvalue başvurusu döndürür. fonksiyon çıktığında yerel bir işlev çünkü Ancak, rvalue referans bağlı geçici aslen, imha edilecek o. Bu noktada, geçici imha edilecek. Tüm bunların net etkisi, s
'un hemen bir sarkan referans olmasıdır.
Orijinal for_each
ile, funker'in değere göre döndürüleceğini ve referansın doğrudan ömrünü uzatarak referansa bağlı olacağını unutmayın.
Herb Sutter bu cppcon konuşma bu bahsediyor: https://www.youtube.com/watch?v=hEx5DNLWGgA. Temel olarak, bir işlevden bir referans/işaretçi döndürdüğünüzde, gerçekten nelere işaret edebileceğine dair çok az güvenli seçenek vardır. referans olarak almak Fonksiyon argümanlar bunlardan biri, ancak bunlar geçici çekmek ve işlevin dönüş sallanmakta neden çünkü const ref ve rvalue ref tarafından işlevleri argümanlar değildir. Bu konu hakkında yazdım: http://www.nirfriedman.com/2016/01/18/writing-good-cpp-by-default-in-the-stl/. Bir functor alıp nesne inşaat önlemek istiyorsanız
, ben sadece referans ileterek alıp hiçbir şey dönecekti. Niye ya? Çünkü, eğer kullanıcı daha sonra functor'a ihtiyaç duymuyorsa, bir geri dönüşü geçebilir ve geri dönüşü yanlış kullanma konusunda endişelenmeyebilirler. Ve sonra ihtiyaç duyarlarsa, onu inşa edebilir, bir değer olarak geçebilir ve sonra kullanabilirler.
template< class InputIt, class UnaryFunction >
void my_for_each(InputIt first, InputIt last, UnaryFunction&& f);
my_functor s{};
my_for_each(v.begin(), v.end(), s);
auto sum = s.sum;
Yapı/yıkım yok, sorun yok. Her ne kadar performans nedenleriyle bunu engellemeye çalışıyorsanız, muhtemelen, functor/lambda'nızın büyük olmadığı, bu da alışılmadık bir durum olduğu için yanlış yönlendirildiğini söyleyebilirim. diğer ince cevap olarak
Dönüş türünüz UnaryFunction && bir referans değerdir. – Loreto
@Loreto Hayır, argümanın değer kategorisine bağlıdır. –
Oh, doğru, anlıyorum. – Loreto