C++ 使用c+的弱绑定+;17

C++ 使用c+的弱绑定+;17,c++,c++14,c++17,weak-references,C++,C++14,C++17,Weak References,我正在开发一个处理框架,在这个框架中回调被注册到事件中,为了确保没有对已删除的对象调用回调,我希望使用弱捕获,而不是通过引用捕获。使用C++14和shared\u from\u this()来实现这一点没有问题,但是如何使用C++17和weak\u from\u this()来正确实现这一点呢 下面的示例在使用C++17时不打印任何内容。我使用的是g++6.3.0-18 #define CXX17 // When this is defined, nothing is printed #ifd

我正在开发一个处理框架,在这个框架中回调被注册到事件中,为了确保没有对已删除的对象调用回调,我希望使用弱捕获,而不是通过引用捕获。使用
C++14
shared\u from\u this()
来实现这一点没有问题,但是如何使用
C++17
weak\u from\u this()
来正确实现这一点呢

下面的示例在使用
C++17
时不打印任何内容。我使用的是g++6.3.0-18

#define CXX17  // When this is defined, nothing is printed
#ifdef CXX17
# include <experimental/memory>
# include <experimental/functional>
  template <typename T>
  using enable_shared_from_this = std::experimental::enable_shared_from_this<T>;
#else
# include <memory>
# include <functional>
  template <typename T>
  using enable_shared_from_this = std::enable_shared_from_this<T>;
#endif

#include <thread>
#include <mutex>
#include <condition_variable>
#include <atomic>
#include <iostream>

struct A : enable_shared_from_this<A> {
  int a;
  A() : a(7) {}
  auto getptr() {
#ifdef CXX17
    return this->weak_from_this();
#else
    auto sptr = shared_from_this();
    auto wptr = std::weak_ptr<decltype(sptr)::element_type>(sptr);
    sptr.reset();  // Drop strong referencing
    return wptr;
#endif
  }
};

std::condition_variable condition;
std::mutex mutex;
std::atomic<bool> start0{false};
std::atomic<bool> start1{false};

std::shared_ptr<A> g_a;

static void thread_func0() {
  auto w_a = g_a->getptr();

  std::unique_lock<std::mutex> lock {mutex};
  condition.wait(lock, [&]() {
    return start0.load();
  });
  std::this_thread::sleep_for(std::chrono::microseconds(10));
  if (auto t = w_a.lock()) {
    std::cout << t->a << std::endl;
  }
}

static void thread_func1() {
  std::unique_lock<std::mutex> lock {mutex};
  condition.wait(lock, [&]() {
      return start1.load();
    });
  std::this_thread::sleep_for(std::chrono::microseconds(10000));
  g_a = nullptr;
}

int main() {
  g_a = std::make_shared<A>();

  std::thread thread0(thread_func0);
  std::thread thread1(thread_func1);

  start0 = true;
  start1 = true;
  condition.notify_all();

  thread0.join();
  thread1.join();

  return 0;
}
#定义CXX17//定义此项后,不会打印任何内容
#ifdef CXX17
#包括
#包括
模板
使用enable_shared_from_this=std::experimental::enable_shared_from_this;
#否则
#包括
#包括
模板
使用enable_shared_from_this=std::enable_shared_from_this;
#恩迪夫
#包括
#包括
#包括
#包括
#包括
结构A:从\u中启用\u共享\u{
INTA;
A():A(7){}
自动获取ptr(){
#ifdef CXX17
从_this()返回此->弱_;
#否则
auto sptr=从_this()共享的_;
自动wptr=std::弱ptr(sptr);
sptr.reset();//删除强引用
返回wptr;
#恩迪夫
}
};
std::条件\可变条件;
std::互斥互斥;
std::原子开始0{false};
std::原子start1{false};
std::共享ptr g_a;
静态无效线程_func0(){
自动w_a=g_a->getptr();
std::unique_lock{mutex};
条件。等待(锁定,[&](){
返回start0.load();
});
std::this_thread::sleep_for(std::chrono::微秒(10));
如果(自动t=w_a.lock()){

std::cout a这里有一个更简化的示例:

#include <experimental/memory>
#include <iostream>

template <typename T>
using enable_shared_from_this = std::experimental::enable_shared_from_this<T>;

struct A : enable_shared_from_this<A> {
  int a;
  A() : a(7) {}
};

int main() {
    auto sp = std::make_shared<A>();

    auto wp = sp->weak_from_this();
    if (auto s = wp.lock()) {
        std::cout << s->a << std::endl;
    }
}
致:

auto sp=std::experimental::shared_ptr(新A);

然后,选择加入机制匹配
shared_ptr
类型并做正确的事情,您将得到一个有效的
weak_ptr
(a
std::experimental::weak_ptr
),
lock()
为您提供基础
A
的共享所有权,程序打印7。

您是对的,我已经更改了此项。我已经更改了代码,因此
共享的ptr
重置得足够晚,可以打印输出(适用于C++14,但不适用于C++17)非常感谢-这是有道理的。不过,当我使用
std::shared_ptr
而不是
std::experimental::shared_ptr
时,没有触发
static_assert
。再次感谢。看看如何从这个
实现
std::enable_shared_,我明白了为什么捕获我的inco不是那么简单正确的用法。
auto sp = std::make_shared<A>();
auto sp = std::experimental::shared_ptr<A>(new A);