Share via


make_unique

Creates and returns a unique_ptr to an object of the specified type, which is constructed by using the specified arguments.

// make_unique<T>
template<class T, 
    class... Types>
    unique_ptr<T> make_unique(Types&&... Args)
    {
    return (unique_ptr<T>(new T(forward<Types>(Args)...))); 
    }

// make_unique<T[]>
template<class T>
    make_unique(size_t Size) 
    { 
    return (unique_ptr<T>(new Elem[Size]())); 
    }

// make_unique<T[N]> disallowed
template<class T, 
    class... Types>
    typename enable_if<extent<T>::value != 0, 
        void>::type make_unique(Types&&...) = delete; 

Parameters

  • T
    The type of the object that the unique_ptr will point to.

  • Types
    The types of the constructor arguments specified by Args.

  • Args
    The arguments to be passed to the constructor of the object of type T.

  • Elem
    An array of elements of type T.

  • Size
    The number of elements to allocate space for in the new array.

Return Value

A unique_ptr to an object of the specified type T.

Remarks

The first overload is used for single objects, the second overload is invoked for arrays, and the third overload prevents the prevents you from specifying an array size in the type argument (make_unique<T[N]>); this construction is not supported by the current standard. When you use make_unique to create a unique_ptr to an array, you have to initialize the array elements separately. If you are considering this overload, perhaps a better choice is to use a std::vector.

Because make_unique is carefully implemented for exception safety, we recommend that you use make_unique instead of directly calling unique_ptr constructors.

Example

The following example shows how to use make_unique. For more examples, see How to: Create and Use unique_ptr Instances.

class Animal
{
private:
    std::wstring genus;
    std::wstring species;
    int age;
    double weight;
public:
    Animal(const wstring&, const wstring&, int, double){/*...*/ }
    Animal(){}
};

void MakeAnimals()
{
    // Use the Animal default constructor.
    unique_ptr<Animal> p1 = make_unique<Animal>();

    // Use the constructor that matches these arguments
    auto p2 = make_unique<Animal>(L"Felis", L"Catus", 12, 16.5);

    // Create a unique_ptr to an array of 5 Animals
    unique_ptr<Animal[]> p3 = make_unique<Animal[]>(5);

    // Initialize the elements
    p3[0] = Animal(L"Rattus", L"norvegicus", 3, 2.1);
    p3[1] = Animal(L"Corynorhinus", L"townsendii", 4, 1.08);

    // auto p4 = p2; //C2280

    vector<unique_ptr<Animal>> vec;
    // vec.push_back(p2); //C2280 
    // vector<unique_ptr<Animal>> vec2 = vec; // C2280 

    // OK. p2 no longer points to anything
    vec.push_back(std::move(p2)); 

    // unique_ptr overloads operator bool
    wcout << boolalpha << (p2 == false) << endl; // Prints "true" 

    // OK but now you have two pointers to the same memory location
    Animal* pAnimal = p2.get();

    // OK. p2 no longer points to anything
    Animal* p5 = p2.release();
}

When you see error C2280 in connection with a unique_ptr, it is almost certainly because you are attempting to invoke its copy constructor, which is a deleted function.

Requirements

<memory>

See Also

Tasks

How to: Create and Use unique_ptr Instances