C++ 从基类继承std::shared_时,std::bad_弱_ptr

C++ 从基类继承std::shared_时,std::bad_弱_ptr,c++,c++11,clang,standard-library,libc++,C++,C++11,Clang,Standard Library,Libc++,首先,这个问题似乎与同时使用clang(任何版本)和高于6.5.0版本的libstdc++有关 我在代码库中使用以下习惯用法向用户隐藏实现: #include <memory> class myclass : public std::enable_shared_from_this<myclass> { class impl; protected: myclass() = default; public: myclass(myclass&&

首先,这个问题似乎与同时使用clang(任何版本)和高于6.5.0版本的libstdc++有关

我在代码库中使用以下习惯用法向用户隐藏实现:

#include <memory>

class myclass : public std::enable_shared_from_this<myclass> {
  class impl;

protected:
  myclass() = default;

public:
  myclass(myclass&&) = delete;
  myclass(myclass const&) = delete;
  myclass& operator=(myclass&&) = delete;
  myclass& operator=(myclass const&) = delete;
  virtual ~myclass() = default;

  static std::shared_ptr<myclass> create();

  int get();
};

class myclass::impl : public myclass {
public:
  using myclass::myclass;

  int get_impl() {
    return 33;
  }
};

std::shared_ptr<myclass> myclass::create() {
  return std::make_shared<impl>();
}

int myclass::get() {
  return static_cast<impl*>(this)->get_impl();
}

int main() {
  auto ref = myclass::create();
  return ref->shared_from_this()->get();
}
使用以下回溯:

#0  0x00007ffa76a7de97 in raise () from /lib/x86_64-linux-gnu/libc.so.6
#1  0x00007ffa76a7f801 in abort () from /lib/x86_64-linux-gnu/libc.so.6
#2  0x00007ffa774728fb in ?? () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#3  0x00007ffa77478d3a in ?? () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#4  0x00007ffa77478d95 in std::terminate() () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#5  0x00007ffa77478fe8 in __cxa_throw () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#6  0x0000000000404f7c in std::__throw_bad_weak_ptr() ()
#7  0x0000000000404e92 in std::__shared_count<(__gnu_cxx::_Lock_policy)2>::__shared_count(std::__weak_count<(__gnu_cxx::_Lock_policy)2> const&) ()
#8  0x0000000000404e2f in std::__shared_ptr<myclass, (__gnu_cxx::_Lock_policy)2>::__shared_ptr<myclass, void>(std::__weak_ptr<myclass, (__gnu_cxx::_Lock_policy)2> const&) ()
#9  0x0000000000404df8 in std::shared_ptr<myclass>::shared_ptr<myclass, void>(std::weak_ptr<myclass> const&) ()
#10 0x0000000000403d2c in std::enable_shared_from_this<myclass>::shared_from_this() ()
#11 0x0000000000403ac8 in main ()
尽管此代码在其他平台和/或编译器上运行良好:

  • GCC 7.3.0和“lib/GCC/x86_64-linux-gnu/7.3.0”在同一平台上工作
  • Clang3.8.0和“lib/gcc/x86_64-linux-gnu/6.5.0”可以在另一个平台上工作
  • Clang 7.0.1和“lib/gcc/x86_64-linux-gnu/6.5.0”在另一个平台上工作
  • Windows MSVC 15.9.4
总的来说,当使用任何clang版本时,从libstdc++中高于版本6.5.0的父类继承时,
std::make_shared
似乎没有检测到来自
std::shared_from_this
的继承

在保留习惯用法的同时,是否可以解决此问题?

什么可能导致这里的缺陷?
如果这向任何错误追踪者报告(但哪一个是它的核心,因为这似乎是clang和libstdc++之间的互操作性问题)。

正如您所建议的,问题实际上似乎是
std::shared\u ptr
没有从这个
基类检测到
std::enable\u shared\u。在我的机器上工作的一个解决方法:

std::shared_ptr<myclass> myclass::create() {
    return std::shared_ptr<myclass>{static_cast<myclass*>(new impl{})};
}
std::shared\ptr myclass::create(){
返回std::shared_ptr{static_cast(newimpl{})};
}

至于在何处报告错误:我会在llvm bugtracker上报告它,毕竟它与GCC一起工作,并且与GCCs库兼容是大家的兴趣所在。

您使用的是libc++吗?错误似乎来自libstdc++内部,即GNU的库,而不是clang的库。无论如何,我都不确定原因……哦,我是说GNU库libstdc++,我更正了这个
clang version 6.0.0-1ubuntu2 (tags/RELEASE_600/final)
Selected GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/7.3.0
std::shared_ptr<myclass> myclass::create() {
    return std::shared_ptr<myclass>{static_cast<myclass*>(new impl{})};
}