2011-06-13 8 views
5

सी ++ 03 मानक लाइब्रेरी एक क्लास को टाइप करने के दौरान सरल टेम्पलेट प्रकार तर्कों का उपयोग करता है जो आवंटक होने के लिए है। यह संभव है क्योंकि टेम्पलेट्स सी ++ में कैसे काम करते हैं। हालांकि, यह बहुत सरल नहीं है और आपको पता नहीं हो सकता कि वास्तव में किस प्रकार की परिभाषा दिखनी चाहिए - खासकर गैर मानक प्रकारों के मामले में।सी ++ आवंटन प्रकार तर्कों के लिए डिजाइन पैटर्न

मैंने सोचा कि एडाप्टर कक्षाओं को चलाने के लिए यह एक अच्छा विचार हो सकता है। मैं एक उदाहरण बना लिया है आप को दिखाने के लिए मैं क्या मतलब है:

#ifndef HPP_ALLOCATOR_ADAPTOR_INCLUDED 
#define HPP_ALLOCATOR_ADAPTOR_INCLUDED 


#include <memory> 


template<typename T> 
struct allocator_traits; 

template<typename T, class allocator_type = std::allocator<T>> 
class allocator_adaptor; 


template<> 
struct allocator_traits<void> 
{ 
    typedef std::allocator<void>::const_pointer const_pointer; 
    typedef std::allocator<void>::pointer  pointer; 
    typedef std::allocator<void>::value_type value_type; 
}; 

template<typename T> 
struct allocator_traits 
{ 
    typedef typename std::allocator<T>::const_pointer const_pointer; 
    typedef typename std::allocator<T>::const_reference const_reference; 
    typedef typename std::allocator<T>::difference_type difference_type; 
    typedef typename std::allocator<T>::pointer   pointer; 
    typedef typename std::allocator<T>::reference  reference; 
    typedef typename std::allocator<T>::size_type  size_type; 
    typedef typename std::allocator<T>::value_type  value_type; 
}; 


template<class allocator_type> 
class allocator_adaptor<void, allocator_type> 
    : public allocator_traits<void> 
{ 
public: 
    template<typename U> struct rebind { typedef allocator_adaptor<U, allocator_type> other; }; 
}; 

template<typename T, class allocator_type> 
class allocator_adaptor 
    : public allocator_traits<T> 
{ 
private: 
    allocator_type m_impl; 

public: 
    template<typename U> struct rebind { typedef allocator_adaptor<U, allocator_type> other; }; 

    allocator_adaptor() throw() /*noexcept*/; 
    allocator_adaptor(allocator_adaptor const&) throw() /*noexcept*/; 
    allocator_adaptor(allocator_type const&) throw() /*noexcept*/; 
    template<typename U> allocator_adaptor(allocator_adaptor<U, allocator_type> const&) throw() /*noexcept*/; 
    ~allocator_adaptor() throw(); 

    pointer  address(reference x) const /*noexcept*/; 
    const_pointer address(const_reference x) const /*noexcept*/; 

    pointer allocate (size_type, allocator_traits<void>::const_pointer hint = 0); 
    void  deallocate(pointer p, size_type n) /*noexcept*/; 
    size_type max_size () const throw() /*noexcept*/; 

    template<class U, typename... argument_types> void construct(U* p, argument_types&&... args); 
    template<class U> void destroy(U* p); 
}; 


#endif /* HPP_ALLOCATOR_ADAPTOR_INCLUDED */ 

अंतर्गत प्रयोग स्पष्ट होना चाहिए। यहां कुछ उपयोग उदाहरण है।

template<class allocator_type> 
int max_size(allocator_type const& alloc) 
{ 
    // we don't know what kind of max_szie function will be called. 
    return alloc.max_size(); 
} 

template<typename T> 
int max_size(allocator_adaptor<T> const& alloc) 
{ 
    // we know what kind of max_size function will be called. 
    return alloc.max_size(); 
} 

क्या यह सामान्य तरीके की तुलना में एक सुधार है?

+0

मैं कुछ भी पहले लाल पर ऐसा करने के साथ गलत नहीं दिख रहा है तथापि में C++ 0x 'auto' के उपयोग के सबसे एसटीएल उपयोग बहुत सरल बना देता है। – AJG85

उत्तर

0

मुझे अच्छा लग रहा है ... यह जानना अच्छा होगा कि आपके डिज़ाइन का सामान्य तरीका किनारे पर होगा। एक उदाहरण मेरी मदद करने के लिए

बहुत अच्छा होगा "हालांकि, यह नहीं बहुत सीधा है और आप वास्तव में क्या प्रकार परिभाषा की तरह दिखना चाहिए पता नहीं कर सकता"

कैसे करता है आपका कार्यान्वयन std :: आवंटक की तुलना में-प्रकार परिभाषा-भाग में सुधार करता है, कृपया

1

असल में आपका बिंदु construct सदस्य पेश करना है जो विविध तर्कों पर आधारित है और आपको इसके बजाय लिखने की अनुमति देता है:

typedef std::allocator<T> my_alloc; 
my_alloc alloc; 
my_alloc::pointer p = alloc.allocate(10); 
alloc::construct(p, T(param1, param2, param3)); 
alloc::construct(p+1, T(param1, param2, param3)); 
//... 

कुछ आसान प्रपत्र:

alloc::construct(p, param1, param2, param3); 
alloc::construct(p+1, param1, param2, param3); 

यह एक अच्छा फीचर हो रहा है। दूसरी ओर, आप सभी प्रारंभिक मानकों को स्थानांतरित करते हैं, जो पी + 1 ऑब्जेक्ट के उचित प्रारंभिकरण को प्रतिबंधित करेंगे। क्या होगा यदि मैं एकाधिक ऑब्जेक्ट्स के लिए समान पैरामीटर के लिए प्रारंभिकरण दोहराना चाहता हूं। मुझे लगता है कि आपका वर्तमान दृष्टिकोण असफल हो जाएगा (और दुर्भाग्य से संकलन समय पर नहीं)।

+0

मुझे नहीं पता कि आप वास्तव में क्या मतलब है;) आगे की घोषणाएं मौजूदा सी ++ 0x ड्राफ्ट में बिल्कुल उनके जैसी हैं। मुझे लगता है कि आप विविध टेम्पलेट तर्कों के साथ उलझन में हैं। – 0xbadf00d

+0

क्या आप मुझे उस मानक मार्ग पर इंगित कर सकते हैं जहां इसे समझाया गया है? हो सकता है कि मैं वास्तव में भ्रमित हूँ। – ovanes

+0

ज़रूर, आप इसे (C++ 0x मसौदे में '14.5.3 variadic templates' http://www.open-std.org/jtc1/sc22/WG21/docs/papers/2011/n3242.pdf पर पा सकते हैं) – 0xbadf00d

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