2

I have written a stack class:

template <class child_t>
class stack {
    const size_t c_init_cap = 12;
    size_t m_size;
    size_t m_capacity;
    std::unique_ptr<child_t[]> m_head;
public:
    /**
     * @brief Default constructor
     */
    stack() : m_size{0}, m_capacity{c_init_cap},
        m_head{std::make_unique<child_t[]>(new child_t[m_capacity])}
    {}
    /**
     * @brief Copy constructor (deleted)
     * @param other Reference to an original object
     */
    stack(const stack &other) = delete;
    /**
     * @brief Move constructor (default)
     * @param other R-value reference to an original object
     */
    stack(stack &&other) = default;
    /**
     * @brief Destructor
     */
    ~stack() {}
    /**
     * @brief Move assigment (default)
     * @param other R-value reference to an original object
     */
    stack& operator =(stack &&other) = default;
    /**
     * @brief Pushes a new value into the stack
     * @param value New value
     */
    void push(child_t value) {
        if (m_size == m_capacity) { increase(); }
        m_head[m_size++] = std::move(value);
    }
    /**
     * @brief Pops a top value from the stack
     */
    void pop() { --m_size; }
    /**
     * @brief Returns a reference to a top value of the stack
     * @return Top value
     */
    child_t &top() { return m_head[m_size - 1]; }
    /**
     * @brief Returns a reference to a top value of the stack
     * @return Top value
     */
    const child_t &top() const { return m_head[m_size - 1]; }
    /**
     * @brief Returns a stack size
     * @return Stack size
     */
    size_t size() const { return m_size; }
    /**
     * @brief Checks if the stack is empty
     * @return Check result
     */
    bool empty() const { return m_size == 0; }
private:
    /**
     * @brief Increases the pre-allocated capacity of the buffer doubly
     */
    void increase() {
        m_capacity <<= 1;
        auto tmp = new child_t[m_capacity];
        std::copy(m_head, m_head + m_size - 1, tmp);
        m_head.reset(tmp);
    }
};

But I'm getting an error on build:

/home/Task_3_3/task_3_3/stack.h:20: error: no matching function for call to ‘make_unique<int []>(int*)’
         m_head{std::make_unique<child_t[]>(new child_t[m_capacity])}
                ~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~

What does it mean? And how can I fix?
P.S. I'm learning C++ only, so I am a noobie still...

Denis Sologub
  • 7,277
  • 11
  • 56
  • 123

2 Answers2

6

The correct use of std::make_unique with an array type is to provide the size of the array as argument.

The correct way of initializing m_head would then be m_head{std::make_unique<child_t[]>(m_capacity)}.

François Andrieux
  • 28,148
  • 6
  • 56
  • 87
3

Probably the most important reason to use make_unique is to avoid using new operator. You can read this quesiton for more information: Exception safety and make_unique.

So in your case:

std::make_unique<child_t[]>(m_capacity);
Yola
  • 18,496
  • 11
  • 65
  • 106