微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

具有抽象接口的 CRTP,dynamic_cast 工作但 dynamic_pointer_cast 不

如何解决具有抽象接口的 CRTP,dynamic_cast 工作但 dynamic_pointer_cast 不

我正在考虑维基百科中 CRTP 的基本示例

#include <memory>

// Base class has a pure virtual function for cloning
class AbstractShape {
 public:
  virtual ~AbstractShape() = default;
  virtual std::unique_ptr<AbstractShape> clone() const = 0;
};

// This CRTP class implements clone() for Derived
template <typename Derived>
class Shape : public AbstractShape {
 public:
  std::unique_ptr<AbstractShape> clone() const override {
    return std::make_unique<Derived>(static_cast<Derived const&>(*this));
  }

 protected:
  // We make clear Shape class needs to be inherited
  Shape() = default;
  Shape(const Shape&) = default;
  Shape(Shape&&) = default;
};

class Square : public Shape<Square> {};

在 main() 函数中,以下编译

Square sq1;
std::unique_ptr<AbstractShape> sq2 = sq1.clone();
dynamic_cast<Square*>(sq2.get());

但是下面没有

Square sq1;
std::unique_ptr<AbstractShape> sq2 = sq1.clone();
std::dynamic_pointer_cast<Square>(sq2.get());

编译器给出错误

error: no matching function for call to ‘dynamic_pointer_cast<Square>(std::unique_ptr<AbstractShape>::pointer)’
   std::dynamic_pointer_cast<Square>(sq2.get());
                                              ^
In file included from /usr/include/c++/7/bits/shared_ptr.h:52:0,from /usr/include/c++/7/memory:81,from /home/mario/dev/bayesmix/test/crtp_aux.h:1,from /home/mario/dev/bayesmix/test/crtp.cc:2:
/usr/include/c++/7/bits/shared_ptr_base.h:1571:5: note: candidate: template<class _Tp,class _Tp1,__gnu_cxx::_Lock_policy _Lp> std::__shared_ptr<_Tp1,_Lp> std::dynamic_pointer_cast(const std::__shared_ptr<_Tp2,_Lp>&)
     dynamic_pointer_cast(const __shared_ptr<_Tp1,_Lp>& __r) noexcept
     ^~~~~~~~~~~~~~~~~~~~
/usr/include/c++/7/bits/shared_ptr_base.h:1571:5: note:   template argument deduction/substitution Failed:
/home/mario/dev/bayesmix/test/crtp.cc:37:46: note:   mismatched types ‘const std::__shared_ptr<_Tp2,_Lp>’ and ‘std::unique_ptr<AbstractShape>::pointer {aka AbstractShape*}’
   std::dynamic_pointer_cast<Square>(sq2.get());

基本上是说模板推导失败。但是,Square 不是模板化的,也不是 AbstractShape

解决方法

std::shared_ptr<AbstractShape> sq2 = sq1.clone();
auto sq3 = std::dynamic_pointer_cast<Square>(sq2);

动态指针转换转换共享的ptr。失败的模板推导是 cast 函数的推导。

,

您只能传递一个 str="1w 2d 1h" regex="([0-9])w ([0-9])d ([0-9])h" if [[ $str =~ $regex ]] then week="${BASH_REMATCH[1]}" day="${BASH_REMATCH[2]}" hour="${BASH_REMATCH[3]}" echo $week --- $day ---- $hour fi 作为 shared_ptr 的参数。但是,您传递了一个原始指针。所以我想你有几个选择。

  1. 只需使用第一种方法(如果您不打算将其变成 dynamic_pointer_cast
  2. shared_ptr 转换为 sq2 并传递它(不带 shared_ptr

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。