2012-04-14 22 views
11

Theo dõi tới this bài Tôi tự hỏi cách thực hiện của nó make_unique phát với phân bổ các mảng đệm tạm thời của hàm như trong đoạn mã sau.C++ Mảng và make_unique

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

này có thể được thay thế bằng một số cuộc gọi đến make_unique và sẽ các [] -version của delete được sử dụng sau đó?

Trả lời

16

Dưới đây là một giải pháp (ngoài 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); 
} 

Ghi chú:

  1. mới T [n] nên chỉ mặc định xây dựng n T's.

Vì vậy make_unique (n) chỉ nên mặc định xây dựng n T.

  1. Các vấn đề như thế này góp phần tạo nên make_unique không được đề xuất trong C++ 11. Một vấn đề khác là: Chúng tôi có xử lý các thông số tùy chỉnh không?

Đây không phải là câu hỏi không trả lời được. Nhưng họ là những câu hỏi chưa được trả lời đầy đủ.

+0

... nhưng những câu hỏi này đã được (một phần) được trả lời trong C++ 14 và make_unique giờ đây [phong phú hơn] (http://en.cppreference.com/w/cpp/memory/unique_ptr/make_unique). – einpoklum

+0

@einpoklum: Đúng. Lưu ý ngày trên Q/A. –

4

tôi nhận nó làm việc với mã này:

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