Сохранение указателя путем продления жизни захвата

Можно ли продлить жизнь unique_ptr захватывая его в лямбду и продлевая жизнь лямбды?

Я пытался, но получая синтаксические ошибки с a=move(a) выражение.

#include <cstdio>
#include <functional>
#include <memory>
#include <iostream>

using namespace std;

struct A {
  A() { cout << "A()" << endl; }
 ~A() { cout << "~A()" << endl; }
};

int main() {
  std::function<void ()> f;
  {
    std::unique_ptr<A> a(new A());
    f = [a=move(a)] () mutable { return; };
  }
  return 0;
}

1 ответ

Ну, проблема с вашим кодом std::function, Он не очень удобен для перемещения, так как требует, чтобы его вызывали, чтобы он был копируемым / присваиваемым, чего нет у вашей лямбды из-за использования только типа перемещения, unique_ptr в вашем примере.

Есть много примеров, которые могут предоставить вам дружественную версию std::function,

Я пришел сюда с быстрой, хакерской и, вероятно, склонной к ошибкам, но "работающей на моей машине" той же версией:

#include <memory>
#include <iostream>
#include <type_traits>


struct A {
  A() { std::cout << "A()" << std::endl; }
 ~A() { std::cout << "~A()" << std::endl; }
};

template <typename Functor>
struct Holder
{
    static void call(char* sbo) {
        Functor* cb = reinterpret_cast<Functor*>(sbo);
        cb->operator()();
    }

    static void deleter(char* sbo) {
        auto impl = reinterpret_cast<Functor*>(sbo);
        impl->~Functor();
    }

};

template <typename Sign> struct Function;

template <>
struct Function<void()>
{
    Function() = default;
    ~Function() {
        deleter_(sbo_);
    }

    template <typename F>
    void operator=(F&& f)
    {
        using c = typename std::decay<F>::type;
        new (sbo_) c(std::forward<F>(f));
        call_fn_ = Holder<c>::call;
        deleter_ = Holder<c>::deleter;
    }

    void operator()() {
        call_fn_(sbo_);
    }

    typedef void(*call_ptr_fn)(char*);
    call_ptr_fn call_fn_;
    call_ptr_fn deleter_;
    char sbo_[256] = {0,};
};

int main() {
  Function<void()> f;
  {
      std::unique_ptr<A> a(new A());
      f = [a=move(a)] () mutable { return; };
  }
  std::cout << "Destructor should not be called before this" << std::endl;
  return 0;
}

Попробуйте сами: /questions/37374244/vyigruzka-bytearray-s-ispolzovaniem-actionscript-3/37374253#37374253

Другие вопросы по тегам