2012-04-14 20 views
11

this पोस्ट के अनुवर्ती के रूप में मुझे आश्चर्य है कि make_unique का कार्यान्वयन कैसे कार्य-अस्थायी बफर सरणी को आवंटित करने के साथ चलता है जैसे कि निम्न कोड में।सी ++ Arrays और make_unique

f() 
{ 
    auto buf = new int[n]; // temporary buffer 
    // use buf ... 
    delete [] buf; 
} 

इस make_unique करने के लिए कुछ कॉल के साथ प्रतिस्थापित किया जा सकता है और [] -संस्करण हटाने की तो इस्तेमाल किया जाएगा?

उत्तर

16

यहाँ (माइक के अतिरिक्त) एक और उपाय है

  1. नई टी [n] डिफ़ॉल्ट रूप से एन टी का निर्माण करना चाहिए।

तो make_unique (n) को डिफ़ॉल्ट रूप से एन टी का निर्माण करना चाहिए।

  1. इस तरह के मुद्दों को C++ 11 में प्रस्तावित नहीं किया गया है। एक और मुद्दा यह है: क्या हम कस्टम डेलेटर्स को संभालते हैं?

ये असंभव प्रश्न नहीं हैं। लेकिन वे ऐसे प्रश्न हैं जिनका अभी तक पूरी तरह उत्तर नहीं दिया गया है।

+0

... लेकिन इन प्रश्नों को आंशिक रूप से सी ++ 14 में उत्तर दिया गया है, और make_unique अब [अमीर] (http://en.cppreference.com/w/cpp/memory/unique_ptr/make_unique) है। – einpoklum

+0

@ एनोपोकलम: सही। क्यू/ए पर तारीख नोट करें। –

4

मैं इसे इस कोड के साथ काम कर ली:

#include <type_traits> 
#include <utility> 
#include <memory> 

template <class T, class ...Args> 
typename std::enable_if 
< 
    !std::is_array<T>::value, 
    std::unique_ptr<T> 
>::type 
make_unique(Args&& ...args) 
{ 
    return std::unique_ptr<T>(new T(std::forward<Args>(args)...)); 
} 

template <class T> 
typename std::enable_if 
< 
    std::is_array<T>::value, 
    std::unique_ptr<T> 
>::type 
make_unique(std::size_t n) 
{ 
    typedef typename std::remove_extent<T>::type RT; 
    return std::unique_ptr<T>(new RT[n]); 
} 

int main() 
{ 
    auto p1 = make_unique<int>(3); 
    auto p2 = make_unique<int[]>(3); 
} 

नोट्स::

#include <memory> 
#include <utility> 

namespace Aux { 
    template<typename Ty> 
    struct MakeUnique { 
     template<typename ...Args> 
     static std::unique_ptr<Ty> make(Args &&...args) { 
      return std::unique_ptr<Ty>(new Ty(std::forward<Args>(args)...)); 
     } 
    }; 

    template<typename Ty> 
    struct MakeUnique<Ty []> { 
     template<typename ...Args> 
     static std::unique_ptr<Ty []> make(Args &&...args) { 
      return std::unique_ptr<Ty []>(new Ty[sizeof...(args)]{std::forward<Args>(args)...}); 
     } 
    }; 
} 

template<typename Ty, typename ...Args> 
std::unique_ptr<Ty> makeUnique(Args &&...args) { 
    return Aux::MakeUnique<Ty>::make(std::forward<Args>(args)...); 
}