2011-11-23 33 views
20

Bir kapsayıcıyı kapsayıcıdan uzak tutmaksızın bir kapsayıcının (iterator aracılığıyla) benzersiz_ptr öğelerine nasıl erişir? Konteynırdaki bir elemanın iteratörü aldığında, konteynırla birlikte eleman sahipliği devam eder mi? Yineleyicinin unique_ptr'ye erişim kazanması ne zaman yapılır? Bu, unique_ptr'nin gizli bir hareketini gerçekleştiriyor mu?Benzersiz kapsayıcının bir kapsayıcısı üzerinde yineleme

Öğe kapsayıcı öğelerin sahibi olduğunda ve diğer kod yalnızca kapsayıcıdaki öğeleri işlemek istese bile, öğeyi bir kapta (değerle değil) depolamanız gerektiğinde shared_ptr çok kullanıyorum kabın içindeki unique_ptr öğelerine fiilen erişememekten korkuyorum.

Herhangi bir anlayış?

cevap

13

unique_ptr'un bir kopyasını oluşturmaya çalışmadığınız sürece, bunu kullanabilirsiniz. shared_ptr ile olması gerektiği gibi, işaretçinin değerine ulaşmak için yineleyiciyi "ikiye ayırmak" zorundasınız.

Ptr p = v[0]; 

o zaman derleme zamanında öğreneceğim:

#include <vector> 
#include <memory> 
#include <iostream> 

template <class C> 
void 
display(const C& c) 
{ 
    std::cout << '{'; 
    if (!c.empty()) 
     std::cout << *c.front(); 
    for (auto i = std::next(c.begin()); i != c.end(); ++i) 
     std::cout << ", " << **i; 
    std::cout << "}\n"; 
} 

int main() 
{ 
    typedef std::unique_ptr<int> Ptr; 
    std::vector<Ptr> v; 
    for (int i = 1; i <= 5; ++i) 
     v.push_back(Ptr(new int(i))); 
    display(v); 
    for (auto i = v.begin(); i != v.end(); ++i) 
     **i += 2; 
    display(v); 
} 

Bunu yaparsanız (yanlışlıkla) unique_ptr bir kopyasını: Burada kısa bir örnek. Bir çalışma zamanı hatasına neden olmaz. Kullanım durumunuz neden container<unique_ptr<T>>'un yapıldığıdır. İşler sadece işe yaramaz ve eğer yapmazlarsa problem, çalışma zamanı yerine derleme zamanında görünür. Yani kodlayın ve derleme zamanı hatasını anlamıyorsanız, o zaman buraya başka bir soru sorun. auto ile

+0

Tamam, sanırım bu benim için bazı şeyleri açıklığa kavuşturuyor. Yeni for_each işlevini, parametresi öğeye göre değil, öğeye göre geçirilen bir lambda ile kullanma alışkanlığımdaydım, ancak denemekten kaçınmak istiyorsam, unique_ptr öğeleri için başvuru yapmak zorunda kalacağım sanırım kopyala/taşı. Not; Yineleyiciyi bir kez işaretlediğimde ve bu sonuca bir atıfta bulunursam, bunun kopyalamaya teşebbüs etmemesini isterim. Demek istediğim: 'için (Container :: iterator it = container.begin(); it! = Container.end(); ++ ++) { unique_ptr & element = &*it; // Kopyalama denemeye mi gerek yok? } ' Teşekkürler Howard, btw. –

+0

Evet, bunun iyi çalışması gerektiğini düşünüyorum. Kodunuzda ekstra bir & amp; var. Ama derleyici size nerede olduğunu söyleyecektir. –

+0

Bunu bir dere olarak belirtebilirsiniz: blah & element = ** it; hala bir kopyası olmadan düşünüyorum. (Muhtemelen daha kullanışlı.) –

32

ve aralık tabanlı bu nisbeten üstün bir hale için döngüler C++, 11:

std::vector< std::unique_ptr<YourClass>> pointers; 
for(auto&& pointer : pointers) { 
    pointer->functionOfYourClass(); 
} 

std::unique_ptr referans & kopyalanmasını önler ve çözümleyecek olmadan uniqe_ptr kullanabilir.

+0

Bu durumda 'auto &' ve 'auto &&' kullanımı arasında bir fark olup olmadığını bilen var mı? Bu referans, her ikisi de – austinmarton

+0

İyi soru derlemek gibi görünüyor çift & http://en.cppreference.com/w/cpp/language/range-for önerir. 'Auto &&' 'nin başlatıcıya bağlı olarak değişkenlik ve tekrarlama olarak çalışabileceğini öneren [bu bağlantı]' yı (http://en.cppreference.com/w/cpp/language/auto) (bkz. Açıklama/1) buldum. Örneğini buna göre uyarlıyorum. – Pascal

İlgili konular