std::make_unique, std::make_unique_for_overwrite

Header: <memory>

Constructs an object of type T and wraps it in a std::unique_ptr.

# Declarations

template< class T, class... Args >
unique_ptr<T> make_unique( Args&&... args );

(since C++14) (until C++23) (only for non-array types)

template< class T, class... Args >
constexpr unique_ptr<T> make_unique( Args&&... args );

(since C++23) (only for non-array types)

template< class T >
unique_ptr<T> make_unique( std::size_t size );

(since C++14) (until C++23) (only for array types with unknown bound)

template< class T >
constexpr unique_ptr<T> make_unique( std::size_t size );

(since C++23) (only for array types with unknown bound)

template< class T, class... Args >
/* unspecified */ make_unique( Args&&... args ) = delete;

(since C++14) (only for array types with known bound)

template< class T >
unique_ptr<T> make_unique_for_overwrite();

(since C++20) (until C++23) (only for non-array types)

template< class T >
constexpr unique_ptr<T> make_unique_for_overwrite();

(since C++23) (only for non-array types)

template< class T >
unique_ptr<T> make_unique_for_overwrite( std::size_t size );

(since C++20) (until C++23) (only for array types with unknown bound)

template< class T >
constexpr unique_ptr<T> make_unique_for_overwrite( std::size_t size );

(since C++23) (only for array types with unknown bound)

template< class T, class... Args >
/* unspecified */ make_unique_for_overwrite( Args&&... args ) = delete;

(since C++20) (only for array types with known bound)

# Parameters

# Return value

std::unique_ptr of an instance of type T.

# Notes

Unlike std::make_shared (which has std::allocate_shared), std::make_unique does not have an allocator-aware counterpart. allocate_unique proposed in P0211 would be required to invent the deleter type D for the std::unique_ptr<T,D> it returns which would contain an allocator object and invoke both destroy and deallocate in its operator().

# Example

#include <cstddef>
#include <iomanip>
#include <iostream>
#include <memory>
#include <utility>
 
struct Vec3
{
    int x, y, z;
 
    // Following constructor is no longer needed since C++20.
    Vec3(int x = 0, int y = 0, int z = 0) noexcept : x(x), y(y), z(z) {}
 
    friend std::ostream& operator<<(std::ostream& os, const Vec3& v)
    {
        return os << "{ x=" << v.x << ", y=" << v.y << ", z=" << v.z << " }";
    }
};
 
// Output Fibonacci numbers to an output iterator.
template<typename OutputIt>
OutputIt fibonacci(OutputIt first, OutputIt last)
{
    for (int a = 0, b = 1; first != last; ++first)
    {
        *first = b;
        b += std::exchange(a, b);
    }
    return first;
}
 
int main()
{
    // Use the default constructor.
    std::unique_ptr<Vec3> v1 = std::make_unique<Vec3>();
    // Use the constructor that matches these arguments.
    std::unique_ptr<Vec3> v2 = std::make_unique<Vec3>(0, 1, 2);
    // Create a unique_ptr to an array of 5 elements.
    std::unique_ptr<Vec3[]> v3 = std::make_unique<Vec3[]>(5);
 
    // Create a unique_ptr to an uninitialized array of 10 integers,
    // then populate it with Fibonacci numbers.
    std::unique_ptr<int[]> i1 = std::make_unique_for_overwrite<int[]>(10);
    fibonacci(i1.get(), i1.get() + 10);
 
    std::cout << "make_unique<Vec3>():      " << *v1 << '\n'
              << "make_unique<Vec3>(0,1,2): " << *v2 << '\n'
              << "make_unique<Vec3[]>(5):   ";
    for (std::size_t i = 0; i < 5; ++i)
        std::cout << std::setw(i ? 30 : 0) << v3[i] << '\n';
    std::cout << '\n';
 
    std::cout << "make_unique_for_overwrite<int[]>(10), fibonacci(...): [" << i1[0];
    for (std::size_t i = 1; i < 10; ++i)
        std::cout << ", " << i1[i];
    std::cout << "]\n";
}

# See also