2012-04-14 16 views
11

Como seguimiento de la publicación this me pregunto cómo su implementación de make_unique juega con la asignación de arreglos de búfer de función temporal como en el siguiente código.Arrays C++ y make_unique

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

puede esto ser reemplazado con algunos llaman a make_unique y tendrá la [] -versión de borrado usarse entonces?

Respuesta

16

Aquí hay otra solución (además de 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); 
} 

Notas:

  1. nuevo T [n] debería simplemente construir por defecto n T's.

Así que make_unique (n) debería simplemente construir por defecto n T's.

  1. Problemas como este contribuyeron a que make_unique no se haya propuesto en C++ 11. Otro problema es: ¿Manejamos eliminadores personalizados?

Estas no son preguntas sin respuesta. Pero son preguntas que aún no han sido respondidas completamente.

+0

... pero estas preguntas han sido (parcialmente) respondidas en C++ 14, y make_unique es ahora [más rico] (http://en.cppreference.com/w/cpp/memory/unique_ptr/make_unique). – einpoklum

+0

@einpoklum: Correcto. Tenga en cuenta la fecha en la Q/A. –

4

lo tengo trabajando con este código:

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