2013-05-23 6 views
15

std::vector एक अस्थिर कंटेनर है, यानी वेक्टर का आकार बदलकर, इटरेटर अमान्य हो सकते हैं। इसके विपरीत, std::list या boost::container::stable_vector स्थिर कंटेनर हैं जो इटेटर को इसी तत्व को हटाने तक वैध रखते हैं।यह जांचने के लिए कि कोई कंटेनर स्थिर है या नहीं

क्या यह जांचने का कोई तरीका है कि कोई कंटेनर स्थिर है या नहीं? उदाहरण के लिए, यदि मेरे पास

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

क्या केवल स्थिर कंटेनर के लिए अनुमति देना और अस्थिर लोगों को मना करना संभव है?

+1

दिलचस्प सवाल। –

+0

यही कारण है कि हमें अवधारणाओं की आवश्यकता है! (मुझे लगता है) –

+0

@ मार्कगार्शिया: यही कारण है कि हमें वास्तव में * सिद्धांतों * की आवश्यकता है। सिद्धांतों के बिना अवधारणाएं ऐसी अर्थपूर्ण आवश्यकताओं को कैप्चर नहीं कर सकती हैं। मुझे यकीन नहीं है कि हम उन्हें जल्द ही प्राप्त करेंगे, हालांकि ... –

उत्तर

6

मुझे नहीं लगता कि ऐसी जानकारी प्रदान करने में कुछ भी उपलब्ध है, लेकिन आप अपनी खुद की विशेषता लिख ​​सकते हैं। हालांकि, आपको इसे इस्तेमाल करने वाले प्रत्येक स्थिर कंटेनर के लिए विशेषज्ञता हासिल करने की आवश्यकता होगी, जो शायद एक विकल्प नहीं है।

#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 
} 

मुझे नहीं लगता कि आप मैन्युअल विशेषज्ञता का उपयोग किए बिना स्वचालित रूप से एक कंटेनर स्थिर हो सकते हैं।


बस मस्ती के लिए, मैं क्या स्थिरता के लिए अवधारणा/स्वयंसिद्ध कैसा दिखेगा लेखन की कोशिश की (concepts और axioms भाषा के लिए एक विस्तार है कि considered for inclusion in C++11 थे जाता है):

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); 
     } 
    } 
} 

सही ढंग से इस बारे में सोच आवश्यकता को कैप्चर करता है कि मूल कंटेनर पर प्रत्येक पुनरावर्तक संशोधित कंटेनर पर संबंधित पुनरावर्तक के बराबर है। यकीन नहीं है कि यह बहुत उपयोगी है, लेकिन इस तरह के सिद्धांतों के साथ आना एक दिलचस्प अभ्यास है :)!

+1

यह बिल्कुल सही है - स्थिर/अस्थिर बहुत ही अमूर्त विचार है। एक वेक्टर आसानी से अपने इटरेटर्स को अमान्य नहीं कर सकता है: जब आप सोचते हैं या यहां तक ​​कि यदि यह करता है तो सरणी का आकार बदल नहीं सकता है, यह मौजूदा मेमोरी ब्लॉक का उपयोग करने में सक्षम हो सकता है (कंपाइलर इत्यादि के आधार पर)। अगर मैं अपना कंटेनर लिखता हूं, तो यह आसानी से स्मृति को पुन: आवंटित नहीं कर सकता है। – cristicbz

+0

उदाहरण के लिए, यदि आप 'boost :: stable_vector' के साथ शीर्षलेख शामिल नहीं करते हैं तो यह विशेषता टूट जाती है। सामान्य रूप से उपयोग करने योग्य होने के लिए, आपको उन सभी वर्गों को घोषित करने की भी आवश्यकता होगी जिन्हें आप इसके लिए विशेषज्ञता दे रहे हैं। – jrok

+0

@jrok: हाँ, यही कारण है कि यह समाधान आदर्श से बहुत दूर है। आदर्श रूप में, यह विशेषता को विशेषज्ञता देने के लिए कंटेनर पुस्तकालयों की ज़िम्मेदारी होगी, लेकिन यह स्पष्ट रूप से एक विकल्प नहीं है। एक अन्य संभावना है कि विशिष्टता (सबसे आम कंटेनरों के अलावा) को छोड़ दें और 'फू' उपयोगकर्ताओं को इंगित करें कि यदि वे किसी अन्य कंटेनर का उपयोग करना चाहते हैं, तो उन्हें विशेषता का विशेषज्ञ होना चाहिए: 'static_assert' इस हिस्से पर अपना ध्यान आकर्षित करेगा प्रलेखन, जो इसे बहुत स्पष्ट करना चाहिए कि कंटेनर स्थिर होना चाहिए। हालांकि, अभी भी बहुत सुविधाजनक नहीं है। –

संबंधित मुद्दे

 संबंधित मुद्दे