- memory[meta header]
- std[meta namespace]
- function template[meta id-type]
- cpp11[meta cpp]
namespace std {
template <class T, class U>
shared_ptr<T>
dynamic_pointer_cast(const shared_ptr<U>& r) noexcept; // (1) C++11
template <class T, class U>
constexpr shared_ptr<T>
dynamic_pointer_cast(const shared_ptr<U>& r) noexcept; // (1) C++26
template <class T, class U>
shared_ptr<T>
dynamic_pointer_cast(shared_ptr<U>&& r) noexcept; // (2) C++20
template <class T, class U>
constexpr shared_ptr<T>
dynamic_pointer_cast(shared_ptr<U>&& r) noexcept; // (2) C++26
}shared_ptr で管理するインスタンスに対して dynamic_cast を行う。
- (1) :
- (2) :
- C++20 : (1)のC++20と同じ
- (1) :
- (2) :
- C++20 : (1)のC++20と同じ
-
rが空であった場合、この関数は空のshared_ptr<T>を返却する。 -
(1) :
return shared_ptr<T>(r, dynamic_cast<typename shared_ptr<T>::element_type*>(r.get()));
- r.get()[link get.md]
-
(2) :
return shared_ptr<T>(std::move(r), dynamic_cast<typename shared_ptr<T>::element_type*>(r.get()));
- std::move[link /reference/utility/move.md]
- r.get()[link get.md]
shared_ptr<T>(dynamic_cast<T*>(r.get()))という方法は未定義動作を引き起こすので使用しないこと。
投げない
#include <memory>
#include <iostream>
struct A {
virtual void call() const {
std::cout << "A::call" << std::endl;
}
virtual ~A() = default;
};
struct B : A {
void call() const override {
std::cout << "B::call()" << std::endl;
}
};
int main()
{
std::shared_ptr<B> b(new B());
std::shared_ptr<A> a = std::static_pointer_cast<A>(b);
// AからBへのダウンキャスト
if (std::shared_ptr<B> result = std::dynamic_pointer_cast<B>(a)) {
result->call();
}
else {
std::cout << "conversion error" << std::endl;
}
}- std::dynamic_pointer_cast[color ff0000]
- std::static_pointer_cast[link static_pointer_cast.md]
B::call()
- C++11
- Clang: 3.0 [mark verified]
- GCC: 4.3.6 [mark verified]
- ICC: ??
- Visual C++: 2008 (TR1) [mark verified], 2010 [mark verified], 2012 [mark verified], 2013 [mark verified]
- LWG Issue 2964. Apparently redundant requirement for
dynamic_pointer_cast- C++20で、実際にキャストされる式
dynamic_cast<typename shared_ptr<T>::element_type*>(r.get())が適格で定義された動作をすることが要件として追加された(dynamic_cast<T*>((U*)nullptr)が適格であるという要件は残る) - この修正は欠陥報告(DR)であり、C++17にも遡及して適用される。C++17では要件がヌルポインタに対する
dynamic_cast<T*>((U*)0)のみを対象としており、ヌルポインタへのdynamic_castは適格であれば常にヌルポインタを返すため、定義された動作であることの要件が実質的に無意味になっていた。実際にキャストされる式に対する要件を課す意図だったため
- C++20で、実際にキャストされる式
- LWG Issue 2996. Missing rvalue overloads for
shared_ptroperations - P3037R6
constexpr std::shared_ptrand friends