带有抽象接口的 CRTP,dynamic_cast 工作但 dynamic_pointer_cast 不工作
CRTP with abstract interface, dynamic_cast working but dynamic_pointer_cast does not
我正在考虑维基百科中 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);
动态指针转换转换共享指针。失败的模板推导是转换函数的推导。
您只能传递 shared_ptr
作为 dynamic_pointer_cast
的参数。但是你传递了一个原始指针。所以我猜你有几个选择。
- 只用第一种方法(如果你不打算把它变成
shared_ptr
)
- 将
sq2
转换为shared_ptr
并传递(不带.get()
)
我正在考虑维基百科中 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);
动态指针转换转换共享指针。失败的模板推导是转换函数的推导。
您只能传递 shared_ptr
作为 dynamic_pointer_cast
的参数。但是你传递了一个原始指针。所以我猜你有几个选择。
- 只用第一种方法(如果你不打算把它变成
shared_ptr
) - 将
sq2
转换为shared_ptr
并传递(不带.get()
)