Aşağıdaki kod ilk bakışta oldukça zararsız görünüyor. Kullanıcı bu işlevi bar()
bazı kütüphane işlevleriyle etkileşim kurmak için kullanır . ( bar()
Geçici olmayan bir değere veya benzerine bir referans döndürdüğünden beri bu uzun bir süre çalışmış olabilir .) Ancak şimdi yeni bir örneğini döndürüyor B
. B
yine a()
yinelenebilir türdeki bir nesneye başvuru döndüren bir işleve sahiptir A
. Kullanıcı, B
döndürülen geçici nesne bar()
yineleme başlamadan önce yok edildiğinden , bir segfault'a yol açan bu nesneyi sorgulamak ister .
Bunun için kimin (kütüphane veya kullanıcı) suçlanacağına kararsızım. Tüm kütüphane dersleri bana temiz görünüyor ve kesinlikle diğer kodlardan çok farklı bir şey yapmıyor (üyelere referanslar döndürme, yığın örnekleri döndürme, ...). Kullanıcı da yanlış bir şey yapmıyor gibi görünüyor, sadece o nesnelerin ömrü boyunca herhangi bir şey yapmadan bazı nesneler üzerinde yineleniyor.
(İlgili bir soru şöyle olabilir: Kodun döngü başlığında birden fazla zincirleme çağrı tarafından alınan bir şey üzerinde kodun "yineleme-aralık-yinelemeli" olmaması gerektiğine dair genel bir kural oluşturulmalıdır. rvalue?)
#include <algorithm>
#include <iostream>
// "Library code"
struct A
{
A():
v{0,1,2}
{
std::cout << "A()" << std::endl;
}
~A()
{
std::cout << "~A()" << std::endl;
}
int * begin()
{
return &v[0];
}
int * end()
{
return &v[3];
}
int v[3];
};
struct B
{
A m_a;
A & a()
{
return m_a;
}
};
B bar()
{
return B();
}
// User code
int main()
{
for( auto i : bar().a() )
{
std::cout << i << std::endl;
}
}