C ++数组和make_unique

时间:2012-04-14 00:07:52

标签: c++ arrays c++11 unique-ptr raii

作为this帖子的后续内容,我想知道make_unique的实现如何与分配函数临时缓冲区数组一起使用,如下面的代码所示。

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

是否可以通过调用make_unique来替换它,然后会使用[] - 版本的删除吗?

2 个答案:

答案 0 :(得分:16)

这是另一种解决方案(除了迈克):

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

注意:

  1. new T [n]应该默认构造n T。
  2. 所以make_unique(n)应该默认构造n T。

    1. 这样的问题导致make_unique没有在C ++ 11中提出。另一个问题是:我们是否处理自定义删除工具?
    2. 这些不是无法回答的问题。但它们是尚未完全回答的问题。

答案 1 :(得分:4)

我使用了这段代码:

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