Here is a code that crash when, in main, line (2) version is used (and line (1) is commented). Weird enough, this code compiles fines with a simple replacement implementation (line (1)) that mimic the behavior of line (2). Of course, if it's an undefined behavior, it can't have a good explanation, but I don't understand why it crashes. Basically, it's a generator implementation coroutine in C++, tested with captures by references. It works always, except when used with unique_ptr (raw pointer works). Just, why ?
#include <iostream>
#include <coroutine>
#include <cassert>
#include <optional>
#include <memory>
using std::cout;
using std::endl;
template<typename T>
class generator
{
public:
    struct promise_type
    {
        std::optional<T> t_;
        promise_type() = default;
        ~promise_type() = default;
        std::suspend_always initial_suspend() { return {}; }
        std::suspend_always final_suspend() noexcept { return {}; }
        void unhandled_exception() {}
        generator get_return_object() { return {std::coroutine_handle<promise_type>::from_promise(*this)}; }
        std::suspend_always yield_value(T t) { t_ = t; return {}; }
        void return_void() {}
    };
private:
    std::coroutine_handle<promise_type> h_;
    generator(std::coroutine_handle<promise_type> h) : h_(h) {}
public:
    generator() = default;
    // ------ Prevent copies
    generator(const generator&) = delete;
    generator& operator=(const generator&) = delete;
    // ------ Allow moves
    generator(generator&& other) noexcept
        : h_(move(other.h_)) // move may be unnecessary, coroutine_handle acts like a lightweight pointer
    {
        other.h_ = {}; // Unlink handle in moved generator
                       // move() does not guarantee to destroy original value
    }
    generator& operator=(generator&& other) noexcept
    {
        h_ = move(other.h_);
        other.h_ = {};
        return *this;
    }
    ~generator()
    {
        if(h_)
        {
            h_.destroy();
            h_ = {};
        }
    }
    bool is_resumable() const
    {
        return h_ && !h_.done();
    }
    bool operator()()
    {
        return resume();
    }
    bool resume()
    {
        assert(is_resumable());
        h_();
        return !h_.done();
    }
    [[nodiscard]] const T& get() const
    {
        return h_.promise().t_.value();
    }
    [[nodiscard]] T& get() // Allow movable
    {
        return h_.promise().t_.value();
    }
};
struct F
{
    /*F(const std::function<generator<int>()>& del)
    {
        handle = del();
    }*/
    template<typename T>
    F(T del)
    {
        handle = del();
    }
    ~F() { cout << "dtor" << endl; }
    generator<int> handle;
};
template<typename T>
struct UniquePtr
{
    UniquePtr(T* t) : t_(t) {}
    UniquePtr(UniquePtr&&) = delete;
    UniquePtr(const UniquePtr&) = delete;
    UniquePtr& operator=(UniquePtr&&) = delete;
    UniquePtr& operator=(const UniquePtr&) = delete;
    ~UniquePtr() { delete t_; }
    T* operator->() const { return t_;}
private:
    T* t_;
};
int main()
{
    int x = 10;
    auto a = [&]() -> generator<int> {
        x = 20;
        co_yield x;
    };
    //UniquePtr<F> ptr(new F(a)); // (1)
    std::unique_ptr<F> ptr(new F(a)); // (2)
    generator<int>& gen = ptr->handle;
    gen();
    cout << gen.get() << "/" << x << endl;
    return 0;
}
EDIT. :
It crashes also a Godbolt (error 139), here is the link : https://godbolt.org/z/cWYY8PKx4. Maybe is it a gcc implementation problem, around std::unique_ptr optimizations? I can't test on other compilers on Godbolt, there is no support for coroutines on clang.
 
     
     
    