1

so I thought adding unique to vector shouldn't work. Why does it work for the below code? Is it cause by not setting copy ctor as "deleted"??

#include <iostream>
#include <vector>
#include <memory>

class Test
{
    public:
        int i = 5;
};


int main()
{
    std::vector<std::unique_ptr<Test>> tests;
    tests.push_back(std::make_unique<Test>());
    
    for (auto &test : tests)
    {
        std::cout << test->i << std::endl;
    }

    for (auto &test : tests)
    {
        std::cout << test->i << std::endl;
    }
}
wlodek14a
  • 63
  • 4
  • 2
    Why do you think you can't make a vector of unique_ptr? You can, as long as you never copy such pointers (you can only _move_ them). – chi Jun 30 '21 at 08:45
  • _I also wonder how 'for' loop references vector elements._ — The for-loop variable is a reference. References do not copy/move anything by themselves. – Daniel Langr Jun 30 '21 at 09:47

2 Answers2

7

There is no copy here, only moves.

In this context, make_unique will produce an instance of unique pointer which is not named, and this push_back sees it as a r-value reference, which it can use as it wants.

It produce pretty much the same result than this code would:

std::vector<std::unique_ptr<Test>> tests;
auto ptr = std::make_unique<Test>();
tests.push_back(std::move(ptr));

This is called move semantics if you want to search more info on the matter. (and this only works from c++11 and beyond)

Julien Lopez
  • 1,021
  • 6
  • 14
  • Welcome, I tried to stay concise, this can get pretty complex pretty fast, and people online explain it way better than I ever will :) – Julien Lopez Jun 30 '21 at 11:11
2

There are two overloads of std::vector::push_back according to https://en.cppreference.com/w/cpp/container/vector/push_back

In your case you will use the one with rvalue-ref so no copying required.

jdfa
  • 659
  • 4
  • 11