2

The problem only appears when adding the ~MyClass() function. I think the error is undefined behaviour or has something to do with the const MyClass& maybe this kind reference doesn't work with emplace_back. Comments explain the rest:

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

struct MyClass
{
    const int x;

    MyClass(int _x) : x(_x)
    {
    }
};

struct MyClass2
{
    std::unique_ptr<MyClass> my;

    MyClass2(const MyClass& my2)
    {
        my.reset(new MyClass(my2.x));
    }
    
    // when adding this function
    // error: static assertion failed: result type must be constructible from input type
    ~MyClass2()
    {
        printf("deleting\n");
    }
};

int main()
{
    MyClass main(12);

    std::vector<MyClass2> ts;

    for (int i = 0; i < 10; ++i)
    {
        ts.emplace_back(main);
    }

    printf("%i\n", ts[0].my->x);

    return 0;
}
deanqx
  • 75
  • 1
  • 7
  • Haven't tested it but surely it should be `printf("%i\n", *(ts[0].x));` You need to dereference the smart pointer to get the integer. – john May 18 '23 at 13:55
  • `*x.get() = y;` can be replaced with `*x = y;`, no need for `get()`. – john May 18 '23 at 13:58
  • There's a close button above. And when it's closed there's a delete button. – john May 18 '23 at 14:00
  • OK, I guess that's because you are the author. Press it if you want the post deleted. – john May 18 '23 at 14:05
  • @deanqx Only higher reputation users see the "close" button. But you can use "delete". It will make the question invisible to most users. You can later "undelete" it if you e.g. have edited it. – user17732522 May 18 '23 at 14:06
  • Adding a destructor removes the implicit move constructor (and assignment operator) that you need for the `std::unique_ptr` member. You can add them back in as `MyClass2(MyClass2&&) = default; MyClass2& operator=(MyClass2&&) = default;` – Caleth May 18 '23 at 15:31
  • That's bad cause `int x` is actually `const` – deanqx May 18 '23 at 15:36

2 Answers2

0

You need to dereference the std::unique_ptr in order to access the data.

int main()
{
    std::vector<MyClass> ts;

    for (int i = 0; i < 10; ++i)
    {
        ts.emplace_back(123);
    }

    // error: use of deleted function 'std::unique_ptr'
    printf("%i\n", *ts[0].x);

    return 0;
}
RandomBits
  • 4,194
  • 1
  • 17
  • 30
-1

Calling the emplace_back function attempts to create a new MyClass2 object and copy that object into the vector. However, unique_ptr objects cannot be copied. Therefore, you need to write a copy constructor for MyClass2 like this

MyClass2(const MyClass2& my2)
{
    my.reset();
}