2012-04-14 12 views
11

In seguito al post this mi chiedo come la sua implementazione di make_unique giochi con l'allocazione di matrici di buffer temporanee di funzioni come nel seguente codice.C++ Array e make_unique

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

questo può essere sostituito con una certa chiamata alla make_unique e sarà la [] -version di cancellazione da utilizzare poi?

risposta

16

Ecco un'altra soluzione (oltre a Mike):

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

Note:

  1. nuovo T [n] dovrebbe solo costruire di default T.

Quindi make_unique (n) dovrebbe semplicemente costruire di default T.

  1. Problemi come questo hanno contribuito a rendere_unique non proposto in C++ 11. Un altro problema è: gestiamo i deleteri personalizzati?

Queste non sono domande irrisolvibili. Ma sono domande a cui non è ancora stata data una risposta completa.

+0

... ma queste domande sono state (parzialmente) risolte in C++ 14 e make_unique ora è [più ricco] (http://en.cppreference.com/w/cpp/memory/unique_ptr/make_unique). – einpoklum

+0

@einpoklum: corretto. Annotare la data sulla Q/A. –

4

ho preso a lavorare con questo codice:

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