2013-05-23 26 views
15

std::vector kararsız bir kapsayıcıdır, yani vektörü yeniden boyutlandırarak yineleyiciler geçersiz hale gelebilir. Buna karşılık, std::list veya boost::container::stable_vector, yineleyicileri ilgili elemanın çıkarılmasına kadar geçerli tutan sabit konteynerlerdir.Konteynerin sabit olup olmadığını nasıl kontrol edilir

Belirli bir kabın sabit olup olmadığını kontrol etmenin bir yolu var mı? Mesela ben varsa

template<template <typename A, typename B=std::allocator<A> > class T=std::list> 
class Foo 
{ 
} 

gibi bir şey sadece stabil konteynerler için izin ve kararsız olanları korusun mümkün mü?

+1

İlginç bir soru. –

+0

Bu yüzden kavramlara ihtiyacımız var! (Sanırım) –

+0

@MarkGarcia: Aslında bu yüzden * aksiyomlara * ihtiyacımız var. Aksiyomsuz kavramlar, bu anlamsal gereklilikleri yakalayamaz. Onlara yakında sahip olacağımızdan emin değilim ... –

cevap

6

Bu tür bilgileri sağlayan bir şey olduğunu düşünmüyorum, ancak kendi özelliğinizi yazabilirsiniz. Bununla birlikte, muhtemelen bir seçenek olmayan, kullanılabilecek her dayanıklı konteyner için uzmanlaşmanız gerekir.

#include <boost/container/vector.hpp> 

#include <iostream> 
#include <type_traits> 
#include <list> 
#include <vector> 

template <template <typename...> class Container> 
struct is_stable 
    : std::false_type 
{}; 

template <> 
struct is_stable<std::list> 
    : std::true_type 
{}; 

template <> 
struct is_stable<boost::container::stable_vector> 
    : std::true_type 
{}; 

template<template <typename...> class Container = std::list> 
class Foo 
{ 
    static_assert(is_stable<Container>::value, "Container must be stable"); 
}; 

int main() 
{ 
    Foo<std::list> f1; // ok 
    Foo<std::vector> f2; // compiler error 
} 

Ben otomatik olarak bir kap manuel uzmanlaşma başvurmadan, istikrarlı olduğunu algılayabilen bir yolu yoktur sanmıyorum.

concept StableGroup<typename C, typename Op> 
    : Container<C> 
{ 
    void operator()(Op, C, C::value_type); 

    axiom Stability(C c, Op op, C::size_type index, C::value_type val) 
    { 
     if (index <= c.size()) 
     { 
      auto it = std::advance(c.begin(), index); 
      op(c, val); 
      return it; 
     } 
     <-> 
     if (index <= c.size()) 
     { 
      op(c, val); 
      return std::advance(c.begin(), index); 
     } 
    } 
} 

doğru bu düşünüyorsanız:


Sadece eğlence için, ben (considered for inclusion in C++11 idi dile uzatma concepts ve axioms edilir) istikrar için konsept/aksiyomdur nasıl görüneceğini yazmaya çalıştı Özgün kapsayıcı üzerindeki her yineleyicinin değiştirilmiş kapsayıcıdaki karşılık gelen yineleyiciye eşdeğer olması gereğini yakalar. Bunun çok kullanışlı olduğundan emin değilsiniz, ancak bu tür aksiyomlarla karşılaşmak ilginç bir alıştırmadır :)!

+1

Bu kesinlikle doğru - kararlı/kararsız çok soyut bir fikir. Bir vektör, yineleyicilerini geçersiz kılmaz: dizinin, düşündüğünüzde veya hatta olsa bile, yeniden boyutlandırmayabilir, kullandığı mevcut bellek bloğunu genişletebilir (derleyiciye bağlı olarak). Kendi konteynırı yazarsam, hafızayı kolayca belirleyebilir. – cristicbz

+0

Örneğin, başlığı "boost :: stable_vector" ile eklemediyseniz, bu özellik sonlandırılır. Genellikle kullanılabilir olmak için, uzman olduğunuz tüm dersleri bildirmeniz gerekiyor. – jrok

+0

@jrok: Evet, bu yüzden bu çözüm ideal olmaktan çok uzak. İdeal olarak, bu özelliği uzmanlaşmak için konteyner kütüphanelerinin sorumluluğu olacaktır, ancak bu açıkça bir seçenek değildir. Başka bir olasılık, özelliği (en yaygın konteynerler dışında) uzmanlık dışı bırakmak ve “Foo” kullanıcılarına, eğer başka bir konteynır kullanmak isterlerse, bu özelliği uzmanlaştırmak zorunda olduklarını belirtmelidir: “static_assert” dikkatlerini bu bölüme çekecektir. Bu doküman, konteynerin stabil olması gerektiğini açıkça ortaya koymalıdır. Yine de pek uygun değil. –

İlgili konular