"std::shared_from_this" 不能被其派生的 类 继承吗?
Can't "std::shared_from_this" be inherited by its derived classes?
不能std::shared_from_this
被派生的类继承吗?
为什么这个代码片段没有仔细编译(检查http://cpp.sh/7llcr)? I have read the documentation(https://en.cppreference.com/w/cpp/memory/enable_shared_from_this),但仍然找不到任何线索。我想了很久。如果能对这个问题有所帮助,我将不胜感激。
这是无法编译的代码片段:
// enable_shared_from_this example
#include <iostream>
#include <memory>
struct C : std::enable_shared_from_this<C> {};
struct D : public C {};
int main () {
std::shared_ptr<D> foo, bar;
foo = std::make_shared<D>();
bar = foo->shared_from_this();
return 0;
}
编译器抱怨:
In file included from /usr/include/c++/4.9/bits/shared_ptr.h:52:0,
from /usr/include/c++/4.9/memory:82,
from 3:
/usr/include/c++/4.9/bits/shared_ptr_base.h: In instantiation of 'std::__shared_ptr<_Tp, _Lp>& std::__shared_ptr<_Tp, _Lp>::operator=(std::__shared_ptr<_Tp1, _Lp>&&) [with _Tp1 = C; _Tp = D; __gnu_cxx::_Lock_policy _Lp = (__gnu_cxx::_Lock_policy)2u]':
/usr/include/c++/4.9/bits/shared_ptr.h:299:4: required from 'std::shared_ptr<_Tp>& std::shared_ptr<_Tp>::operator=(std::shared_ptr<_Tp1>&&) [with _Tp1 = C; _Tp = D]'
14:7: required from here
/usr/include/c++/4.9/bits/shared_ptr_base.h:1001:4: error: no matching function for call to 'std::__shared_ptr<D, (__gnu_cxx::_Lock_policy)2u>::__shared_ptr(std::remove_reference<std::__shared_ptr<C, (__gnu_cxx::_Lock_policy)2u>&>::type)'
__shared_ptr(std::move(__r)).swap(*this);
^
/usr/include/c++/4.9/bits/shared_ptr_base.h:1001:4: note: candidates are:
/usr/include/c++/4.9/bits/shared_ptr_base.h:1145:7: note: std::__shared_ptr<_Tp, _Lp>::__shared_ptr(const std::__weak_ptr<_Tp, _Lp>&, std::nothrow_t) [with _Tp = D; __gnu_cxx::_Lock_policy _Lp = (__gnu_cxx::_Lock_policy)2u]
__shared_ptr(const __weak_ptr<_Tp, _Lp>& __r, std::nothrow_t)
^
/usr/include/c++/4.9/bits/shared_ptr_base.h:1145:7: note: candidate expects 2 arguments, 1 provided
/usr/include/c++/4.9/bits/shared_ptr_base.h:1087:2: note: template<class _Alloc, class ... _Args> std::__shared_ptr<_Tp, _Lp>::__shared_ptr(std::_Sp_make_shared_tag, const _Alloc&, _Args&& ...)
__shared_ptr(_Sp_make_shared_tag __tag, const _Alloc& __a,
^
/usr/include/c++/4.9/bits/shared_ptr_base.h:1087:2: note: template argument deduction/substitution failed:
/usr/include/c++/4.9/bits/shared_ptr_base.h:1001:4: note: cannot convert 'std::move<std::__shared_ptr<C, (__gnu_cxx::_Lock_policy)2u>&>((* & __r))' (type 'std::remove_reference<std::__shared_ptr<C, (__gnu_cxx::_Lock_policy)2u>&>::type {aka std::__shared_ptr<C, (__gnu_cxx::_Lock_policy)2u>}') to type 'std::_Sp_make_shared_tag'
__shared_ptr(std::move(__r)).swap(*this);
^
/usr/include/c++/4.9/bits/shared_ptr_base.h:967:17: note: constexpr std::__shared_ptr<_Tp, _Lp>::__shared_ptr(std::nullptr_t) [with _Tp = D; __gnu_cxx::_Lock_policy _Lp = (__gnu_cxx::_Lock_policy)2u; std::nullptr_t = std::nullptr_t]
constexpr __shared_ptr(nullptr_t) noexcept
^
/usr/include/c++/4.9/bits/shared_ptr_base.h:967:17: note: no known conversion for argument 1 from 'std::remove_reference<std::__shared_ptr<C, (__gnu_cxx::_Lock_policy)2u>&>::type {aka std::__shared_ptr<C, (__gnu_cxx::_Lock_policy)2u>}' to 'std::nullptr_t'
/usr/include/c++/4.9/bits/shared_ptr_base.h:963:2: note: template<class _Tp1> std::__shared_ptr<_Tp, _Lp>::__shared_ptr(std::auto_ptr<_Up>&&)
__shared_ptr(std::auto_ptr<_Tp1>&& __r);
^
/usr/include/c++/4.9/bits/shared_ptr_base.h:963:2: note: template argument deduction/substitution failed:
/usr/include/c++/4.9/bits/shared_ptr_base.h:1001:4: note: 'std::remove_reference<std::__shared_ptr<C, (__gnu_cxx::_Lock_policy)2u>&>::type {aka std::__shared_ptr<C, (__gnu_cxx::_Lock_policy)2u>}' is not derived from 'std::auto_ptr<_Up>'
__shared_ptr(std::move(__r)).swap(*this);
^
/usr/include/c++/4.9/bits/shared_ptr_base.h:951:2: note: template<class _Tp1, class _Del> std::__shared_ptr<_Tp, _Lp>::__shared_ptr(std::unique_ptr<_Up, _Ep>&&)
__shared_ptr(std::unique_ptr<_Tp1, _Del>&& __r)
^
/usr/include/c++/4.9/bits/shared_ptr_base.h:951:2: note: template argument deduction/substitution failed:
/usr/include/c++/4.9/bits/shared_ptr_base.h:1001:4: note: 'std::remove_reference<std::__shared_ptr<C, (__gnu_cxx::_Lock_policy)2u>&>::type {aka std::__shared_ptr<C, (__gnu_cxx::_Lock_policy)2u>}' is not derived from 'std::unique_ptr<_Tp, _Dp>'
__shared_ptr(std::move(__r)).swap(*this);
^
/usr/include/c++/4.9/bits/shared_ptr_base.h:939:11: note: template<class _Tp1> std::__shared_ptr<_Tp, _Lp>::__shared_ptr(const std::__weak_ptr<_Tp1, _Lp>&)
explicit __shared_ptr(const __weak_ptr<_Tp1, _Lp>& __r)
^
/usr/include/c++/4.9/bits/shared_ptr_base.h:939:11: note: template argument deduction/substitution failed:
/usr/include/c++/4.9/bits/shared_ptr_base.h:1001:4: note: 'std::remove_reference<std::__shared_ptr<C, (__gnu_cxx::_Lock_policy)2u>&>::type {aka std::__shared_ptr<C, (__gnu_cxx::_Lock_policy)2u>}' is not derived from 'const std::__weak_ptr<_Tp>'
__shared_ptr(std::move(__r)).swap(*this);
^
/usr/include/c++/4.9/bits/shared_ptr_base.h:931:2: note: template<class _Tp1, class> std::__shared_ptr<_Tp, _Lp>::__shared_ptr(std::__shared_ptr<_Tp1, _Lp>&&)
__shared_ptr(__shared_ptr<_Tp1, _Lp>&& __r) noexcept
^
/usr/include/c++/4.9/bits/shared_ptr_base.h:931:2: note: template argument deduction/substitution failed:
/usr/include/c++/4.9/bits/shared_ptr_base.h:929:31: error: no type named 'type' in 'struct std::enable_if<false, void>'
template<typename _Tp1, typename = typename
^
/usr/include/c++/4.9/bits/shared_ptr_base.h:922:7: note: std::__shared_ptr<_Tp, _Lp>::__shared_ptr(std::__shared_ptr<_Tp, _Lp>&&) [with _Tp = D; __gnu_cxx::_Lock_policy _Lp = (__gnu_cxx::_Lock_policy)2u]
__shared_ptr(__shared_ptr&& __r) noexcept
^
/usr/include/c++/4.9/bits/shared_ptr_base.h:922:7: note: no known conversion for argument 1 from 'std::remove_reference<std::__shared_ptr<C, (__gnu_cxx::_Lock_policy)2u>&>::type {aka std::__shared_ptr<C, (__gnu_cxx::_Lock_policy)2u>}' to 'std::__shared_ptr<D, (__gnu_cxx::_Lock_policy)2u>&&'
/usr/include/c++/4.9/bits/shared_ptr_base.h:918:2: note: template<class _Tp1, class> std::__shared_ptr<_Tp, _Lp>::__shared_ptr(const std::__shared_ptr<_Tp1, _Lp>&)
__shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r) noexcept
^
/usr/include/c++/4.9/bits/shared_ptr_base.h:918:2: note: template argument deduction/substitution failed:
/usr/include/c++/4.9/bits/shared_ptr_base.h:916:31: error: no type named 'type' in 'struct std::enable_if<false, void>'
template<typename _Tp1, typename = typename
^
/usr/include/c++/4.9/bits/shared_ptr_base.h:912:7: note: std::__shared_ptr<_Tp, _Lp>::__shared_ptr(const std::__shared_ptr<_Tp, _Lp>&) [with _Tp = D; __gnu_cxx::_Lock_policy _Lp = (__gnu_cxx::_Lock_policy)2u]
__shared_ptr(const __shared_ptr&) noexcept = default;
^
/usr/include/c++/4.9/bits/shared_ptr_base.h:912:7: note: no known conversion for argument 1 from 'std::remove_reference<std::__shared_ptr<C, (__gnu_cxx::_Lock_policy)2u>&>::type {aka std::__shared_ptr<C, (__gnu_cxx::_Lock_policy)2u>}' to 'const std::__shared_ptr<D, (__gnu_cxx::_Lock_policy)2u>&'
/usr/include/c++/4.9/bits/shared_ptr_base.h:908:2: note: template<class _Tp1> std::__shared_ptr<_Tp, _Lp>::__shared_ptr(const std::__shared_ptr<_Tp1, _Lp>&, _Tp*)
__shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r, _Tp* __p) noexcept
^
/usr/include/c++/4.9/bits/shared_ptr_base.h:908:2: note: template argument deduction/substitution failed:
/usr/include/c++/4.9/bits/shared_ptr_base.h:1001:4: note: candidate expects 2 arguments, 1 provided
__shared_ptr(std::move(__r)).swap(*this);
^
/usr/include/c++/4.9/bits/shared_ptr_base.h:903:9: note: template<class _Deleter, class _Alloc> std::__shared_ptr<_Tp, _Lp>::__shared_ptr(std::nullptr_t, _Deleter, _Alloc)
__shared_ptr(nullptr_t __p, _Deleter __d, _Alloc __a)
^
/usr/include/c++/4.9/bits/shared_ptr_base.h:903:9: note: template argument deduction/substitution failed:
/usr/include/c++/4.9/bits/shared_ptr_base.h:1001:4: note: cannot convert 'std::move<std::__shared_ptr<C, (__gnu_cxx::_Lock_policy)2u>&>((* & __r))' (type 'std::remove_reference<std::__shared_ptr<C, (__gnu_cxx::_Lock_policy)2u>&>::type {aka std::__shared_ptr<C, (__gnu_cxx::_Lock_policy)2u>}') to type 'std::nullptr_t'
__shared_ptr(std::move(__r)).swap(*this);
^
/usr/include/c++/4.9/bits/shared_ptr_base.h:898:2: note: template<class _Deleter> std::__shared_ptr<_Tp, _Lp>::__shared_ptr(std::nullptr_t, _Deleter)
__shared_ptr(nullptr_t __p, _Deleter __d)
^
/usr/include/c++/4.9/bits/shared_ptr_base.h:898:2: note: template argument deduction/substitution failed:
/usr/include/c++/4.9/bits/shared_ptr_base.h:1001:4: note: cannot convert 'std::move<std::__shared_ptr<C, (__gnu_cxx::_Lock_policy)2u>&>((* & __r))' (type 'std::remove_reference<std::__shared_ptr<C, (__gnu_cxx::_Lock_policy)2u>&>::type {aka std::__shared_ptr<C, (__gnu_cxx::_Lock_policy)2u>}') to type 'std::nullptr_t'
__shared_ptr(std::move(__r)).swap(*this);
^
/usr/include/c++/4.9/bits/shared_ptr_base.h:889:2: note: template<class _Tp1, class _Deleter, class _Alloc> std::__shared_ptr<_Tp, _Lp>::__shared_ptr(_Tp1*, _Deleter, _Alloc)
__shared_ptr(_Tp1* __p, _Deleter __d, _Alloc __a)
^
/usr/include/c++/4.9/bits/shared_ptr_base.h:889:2: note: template argument deduction/substitution failed:
/usr/include/c++/4.9/bits/shared_ptr_base.h:1001:4: note: mismatched types '_Tp1*' and 'std::__shared_ptr<C, (__gnu_cxx::_Lock_policy)2u>'
__shared_ptr(std::move(__r)).swap(*this);
^
/usr/include/c++/4.9/bits/shared_ptr_base.h:880:2: note: template<class _Tp1, class _Deleter> std::__shared_ptr<_Tp, _Lp>::__shared_ptr(_Tp1*, _Deleter)
__shared_ptr(_Tp1* __p, _Deleter __d)
^
/usr/include/c++/4.9/bits/shared_ptr_base.h:880:2: note: template argument deduction/substitution failed:
/usr/include/c++/4.9/bits/shared_ptr_base.h:1001:4: note: mismatched types '_Tp1*' and 'std::__shared_ptr<C, (__gnu_cxx::_Lock_policy)2u>'
__shared_ptr(std::move(__r)).swap(*this);
^
/usr/include/c++/4.9/bits/shared_ptr_base.h:870:11: note: template<class _Tp1> std::__shared_ptr<_Tp, _Lp>::__shared_ptr(_Tp1*)
explicit __shared_ptr(_Tp1* __p)
^
/usr/include/c++/4.9/bits/shared_ptr_base.h:870:11: note: template argument deduction/substitution failed:
/usr/include/c++/4.9/bits/shared_ptr_base.h:1001:4: note: mismatched types '_Tp1*' and 'std::__shared_ptr<C, (__gnu_cxx::_Lock_policy)2u>'
__shared_ptr(std::move(__r)).swap(*this);
^
/usr/include/c++/4.9/bits/shared_ptr_base.h:865:17: note: constexpr std::__shared_ptr<_Tp, _Lp>::__shared_ptr() [with _Tp = D; __gnu_cxx::_Lock_policy _Lp = (__gnu_cxx::_Lock_policy)2u]
constexpr __shared_ptr() noexcept
^
/usr/include/c++/4.9/bits/shared_ptr_base.h:865:17: note: candidate expects 0 arguments, 1 provided
继承:
// enable_shared_from_this example
#include <iostream>
#include <memory>
struct C : std::enable_shared_from_this<C> {};
struct D : public C {};
int main () {
std::shared_ptr<D> foo;
foo = std::make_shared<D>();
std::shared_ptr<C> bar = foo->shared_from_this();
return 0;
}
你在class C
中定义了shared_from_this
:所以对象returnsstd::shated_ptr<C>
。没有惊喜。您仍然可以使用 std::dynamic_pointer_cast
.
将其向下转换为 std::shared_ptr<D>
正如@DimityKuzminov 已经指出的那样,shared_from_this()
将始终 return 一个 std::shared_pointer<C>
,当从 std::shared_ptr<D>
调用时也是如此。为了使用 std::dynmaic_pointer_cast
,你的基类还需要有一个像虚析构函数这样的虚函数(否则你的编译器会告诉你 source type is not polymorphic
)。这是一个例子:
// enable_shared_from_this example
#include <iostream>
#include <memory>
struct C : std::enable_shared_from_this<C> {
virtual ~C() = default;
};
template<typename T, typename U>
std::shared_ptr<T>
shared_from(const std::shared_ptr<U> &a)
{
return std::dynamic_pointer_cast<T>(a->shared_from_this());
}
struct D : public C {};
int main () {
std::shared_ptr<D> foo, bar;
foo = std::make_shared<D>();
bar = shared_from<D>(foo);
return 0;
}
不能std::shared_from_this
被派生的类继承吗?
为什么这个代码片段没有仔细编译(检查http://cpp.sh/7llcr)? I have read the documentation(https://en.cppreference.com/w/cpp/memory/enable_shared_from_this),但仍然找不到任何线索。我想了很久。如果能对这个问题有所帮助,我将不胜感激。
这是无法编译的代码片段:
// enable_shared_from_this example
#include <iostream>
#include <memory>
struct C : std::enable_shared_from_this<C> {};
struct D : public C {};
int main () {
std::shared_ptr<D> foo, bar;
foo = std::make_shared<D>();
bar = foo->shared_from_this();
return 0;
}
编译器抱怨:
In file included from /usr/include/c++/4.9/bits/shared_ptr.h:52:0,
from /usr/include/c++/4.9/memory:82,
from 3:
/usr/include/c++/4.9/bits/shared_ptr_base.h: In instantiation of 'std::__shared_ptr<_Tp, _Lp>& std::__shared_ptr<_Tp, _Lp>::operator=(std::__shared_ptr<_Tp1, _Lp>&&) [with _Tp1 = C; _Tp = D; __gnu_cxx::_Lock_policy _Lp = (__gnu_cxx::_Lock_policy)2u]':
/usr/include/c++/4.9/bits/shared_ptr.h:299:4: required from 'std::shared_ptr<_Tp>& std::shared_ptr<_Tp>::operator=(std::shared_ptr<_Tp1>&&) [with _Tp1 = C; _Tp = D]'
14:7: required from here
/usr/include/c++/4.9/bits/shared_ptr_base.h:1001:4: error: no matching function for call to 'std::__shared_ptr<D, (__gnu_cxx::_Lock_policy)2u>::__shared_ptr(std::remove_reference<std::__shared_ptr<C, (__gnu_cxx::_Lock_policy)2u>&>::type)'
__shared_ptr(std::move(__r)).swap(*this);
^
/usr/include/c++/4.9/bits/shared_ptr_base.h:1001:4: note: candidates are:
/usr/include/c++/4.9/bits/shared_ptr_base.h:1145:7: note: std::__shared_ptr<_Tp, _Lp>::__shared_ptr(const std::__weak_ptr<_Tp, _Lp>&, std::nothrow_t) [with _Tp = D; __gnu_cxx::_Lock_policy _Lp = (__gnu_cxx::_Lock_policy)2u]
__shared_ptr(const __weak_ptr<_Tp, _Lp>& __r, std::nothrow_t)
^
/usr/include/c++/4.9/bits/shared_ptr_base.h:1145:7: note: candidate expects 2 arguments, 1 provided
/usr/include/c++/4.9/bits/shared_ptr_base.h:1087:2: note: template<class _Alloc, class ... _Args> std::__shared_ptr<_Tp, _Lp>::__shared_ptr(std::_Sp_make_shared_tag, const _Alloc&, _Args&& ...)
__shared_ptr(_Sp_make_shared_tag __tag, const _Alloc& __a,
^
/usr/include/c++/4.9/bits/shared_ptr_base.h:1087:2: note: template argument deduction/substitution failed:
/usr/include/c++/4.9/bits/shared_ptr_base.h:1001:4: note: cannot convert 'std::move<std::__shared_ptr<C, (__gnu_cxx::_Lock_policy)2u>&>((* & __r))' (type 'std::remove_reference<std::__shared_ptr<C, (__gnu_cxx::_Lock_policy)2u>&>::type {aka std::__shared_ptr<C, (__gnu_cxx::_Lock_policy)2u>}') to type 'std::_Sp_make_shared_tag'
__shared_ptr(std::move(__r)).swap(*this);
^
/usr/include/c++/4.9/bits/shared_ptr_base.h:967:17: note: constexpr std::__shared_ptr<_Tp, _Lp>::__shared_ptr(std::nullptr_t) [with _Tp = D; __gnu_cxx::_Lock_policy _Lp = (__gnu_cxx::_Lock_policy)2u; std::nullptr_t = std::nullptr_t]
constexpr __shared_ptr(nullptr_t) noexcept
^
/usr/include/c++/4.9/bits/shared_ptr_base.h:967:17: note: no known conversion for argument 1 from 'std::remove_reference<std::__shared_ptr<C, (__gnu_cxx::_Lock_policy)2u>&>::type {aka std::__shared_ptr<C, (__gnu_cxx::_Lock_policy)2u>}' to 'std::nullptr_t'
/usr/include/c++/4.9/bits/shared_ptr_base.h:963:2: note: template<class _Tp1> std::__shared_ptr<_Tp, _Lp>::__shared_ptr(std::auto_ptr<_Up>&&)
__shared_ptr(std::auto_ptr<_Tp1>&& __r);
^
/usr/include/c++/4.9/bits/shared_ptr_base.h:963:2: note: template argument deduction/substitution failed:
/usr/include/c++/4.9/bits/shared_ptr_base.h:1001:4: note: 'std::remove_reference<std::__shared_ptr<C, (__gnu_cxx::_Lock_policy)2u>&>::type {aka std::__shared_ptr<C, (__gnu_cxx::_Lock_policy)2u>}' is not derived from 'std::auto_ptr<_Up>'
__shared_ptr(std::move(__r)).swap(*this);
^
/usr/include/c++/4.9/bits/shared_ptr_base.h:951:2: note: template<class _Tp1, class _Del> std::__shared_ptr<_Tp, _Lp>::__shared_ptr(std::unique_ptr<_Up, _Ep>&&)
__shared_ptr(std::unique_ptr<_Tp1, _Del>&& __r)
^
/usr/include/c++/4.9/bits/shared_ptr_base.h:951:2: note: template argument deduction/substitution failed:
/usr/include/c++/4.9/bits/shared_ptr_base.h:1001:4: note: 'std::remove_reference<std::__shared_ptr<C, (__gnu_cxx::_Lock_policy)2u>&>::type {aka std::__shared_ptr<C, (__gnu_cxx::_Lock_policy)2u>}' is not derived from 'std::unique_ptr<_Tp, _Dp>'
__shared_ptr(std::move(__r)).swap(*this);
^
/usr/include/c++/4.9/bits/shared_ptr_base.h:939:11: note: template<class _Tp1> std::__shared_ptr<_Tp, _Lp>::__shared_ptr(const std::__weak_ptr<_Tp1, _Lp>&)
explicit __shared_ptr(const __weak_ptr<_Tp1, _Lp>& __r)
^
/usr/include/c++/4.9/bits/shared_ptr_base.h:939:11: note: template argument deduction/substitution failed:
/usr/include/c++/4.9/bits/shared_ptr_base.h:1001:4: note: 'std::remove_reference<std::__shared_ptr<C, (__gnu_cxx::_Lock_policy)2u>&>::type {aka std::__shared_ptr<C, (__gnu_cxx::_Lock_policy)2u>}' is not derived from 'const std::__weak_ptr<_Tp>'
__shared_ptr(std::move(__r)).swap(*this);
^
/usr/include/c++/4.9/bits/shared_ptr_base.h:931:2: note: template<class _Tp1, class> std::__shared_ptr<_Tp, _Lp>::__shared_ptr(std::__shared_ptr<_Tp1, _Lp>&&)
__shared_ptr(__shared_ptr<_Tp1, _Lp>&& __r) noexcept
^
/usr/include/c++/4.9/bits/shared_ptr_base.h:931:2: note: template argument deduction/substitution failed:
/usr/include/c++/4.9/bits/shared_ptr_base.h:929:31: error: no type named 'type' in 'struct std::enable_if<false, void>'
template<typename _Tp1, typename = typename
^
/usr/include/c++/4.9/bits/shared_ptr_base.h:922:7: note: std::__shared_ptr<_Tp, _Lp>::__shared_ptr(std::__shared_ptr<_Tp, _Lp>&&) [with _Tp = D; __gnu_cxx::_Lock_policy _Lp = (__gnu_cxx::_Lock_policy)2u]
__shared_ptr(__shared_ptr&& __r) noexcept
^
/usr/include/c++/4.9/bits/shared_ptr_base.h:922:7: note: no known conversion for argument 1 from 'std::remove_reference<std::__shared_ptr<C, (__gnu_cxx::_Lock_policy)2u>&>::type {aka std::__shared_ptr<C, (__gnu_cxx::_Lock_policy)2u>}' to 'std::__shared_ptr<D, (__gnu_cxx::_Lock_policy)2u>&&'
/usr/include/c++/4.9/bits/shared_ptr_base.h:918:2: note: template<class _Tp1, class> std::__shared_ptr<_Tp, _Lp>::__shared_ptr(const std::__shared_ptr<_Tp1, _Lp>&)
__shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r) noexcept
^
/usr/include/c++/4.9/bits/shared_ptr_base.h:918:2: note: template argument deduction/substitution failed:
/usr/include/c++/4.9/bits/shared_ptr_base.h:916:31: error: no type named 'type' in 'struct std::enable_if<false, void>'
template<typename _Tp1, typename = typename
^
/usr/include/c++/4.9/bits/shared_ptr_base.h:912:7: note: std::__shared_ptr<_Tp, _Lp>::__shared_ptr(const std::__shared_ptr<_Tp, _Lp>&) [with _Tp = D; __gnu_cxx::_Lock_policy _Lp = (__gnu_cxx::_Lock_policy)2u]
__shared_ptr(const __shared_ptr&) noexcept = default;
^
/usr/include/c++/4.9/bits/shared_ptr_base.h:912:7: note: no known conversion for argument 1 from 'std::remove_reference<std::__shared_ptr<C, (__gnu_cxx::_Lock_policy)2u>&>::type {aka std::__shared_ptr<C, (__gnu_cxx::_Lock_policy)2u>}' to 'const std::__shared_ptr<D, (__gnu_cxx::_Lock_policy)2u>&'
/usr/include/c++/4.9/bits/shared_ptr_base.h:908:2: note: template<class _Tp1> std::__shared_ptr<_Tp, _Lp>::__shared_ptr(const std::__shared_ptr<_Tp1, _Lp>&, _Tp*)
__shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r, _Tp* __p) noexcept
^
/usr/include/c++/4.9/bits/shared_ptr_base.h:908:2: note: template argument deduction/substitution failed:
/usr/include/c++/4.9/bits/shared_ptr_base.h:1001:4: note: candidate expects 2 arguments, 1 provided
__shared_ptr(std::move(__r)).swap(*this);
^
/usr/include/c++/4.9/bits/shared_ptr_base.h:903:9: note: template<class _Deleter, class _Alloc> std::__shared_ptr<_Tp, _Lp>::__shared_ptr(std::nullptr_t, _Deleter, _Alloc)
__shared_ptr(nullptr_t __p, _Deleter __d, _Alloc __a)
^
/usr/include/c++/4.9/bits/shared_ptr_base.h:903:9: note: template argument deduction/substitution failed:
/usr/include/c++/4.9/bits/shared_ptr_base.h:1001:4: note: cannot convert 'std::move<std::__shared_ptr<C, (__gnu_cxx::_Lock_policy)2u>&>((* & __r))' (type 'std::remove_reference<std::__shared_ptr<C, (__gnu_cxx::_Lock_policy)2u>&>::type {aka std::__shared_ptr<C, (__gnu_cxx::_Lock_policy)2u>}') to type 'std::nullptr_t'
__shared_ptr(std::move(__r)).swap(*this);
^
/usr/include/c++/4.9/bits/shared_ptr_base.h:898:2: note: template<class _Deleter> std::__shared_ptr<_Tp, _Lp>::__shared_ptr(std::nullptr_t, _Deleter)
__shared_ptr(nullptr_t __p, _Deleter __d)
^
/usr/include/c++/4.9/bits/shared_ptr_base.h:898:2: note: template argument deduction/substitution failed:
/usr/include/c++/4.9/bits/shared_ptr_base.h:1001:4: note: cannot convert 'std::move<std::__shared_ptr<C, (__gnu_cxx::_Lock_policy)2u>&>((* & __r))' (type 'std::remove_reference<std::__shared_ptr<C, (__gnu_cxx::_Lock_policy)2u>&>::type {aka std::__shared_ptr<C, (__gnu_cxx::_Lock_policy)2u>}') to type 'std::nullptr_t'
__shared_ptr(std::move(__r)).swap(*this);
^
/usr/include/c++/4.9/bits/shared_ptr_base.h:889:2: note: template<class _Tp1, class _Deleter, class _Alloc> std::__shared_ptr<_Tp, _Lp>::__shared_ptr(_Tp1*, _Deleter, _Alloc)
__shared_ptr(_Tp1* __p, _Deleter __d, _Alloc __a)
^
/usr/include/c++/4.9/bits/shared_ptr_base.h:889:2: note: template argument deduction/substitution failed:
/usr/include/c++/4.9/bits/shared_ptr_base.h:1001:4: note: mismatched types '_Tp1*' and 'std::__shared_ptr<C, (__gnu_cxx::_Lock_policy)2u>'
__shared_ptr(std::move(__r)).swap(*this);
^
/usr/include/c++/4.9/bits/shared_ptr_base.h:880:2: note: template<class _Tp1, class _Deleter> std::__shared_ptr<_Tp, _Lp>::__shared_ptr(_Tp1*, _Deleter)
__shared_ptr(_Tp1* __p, _Deleter __d)
^
/usr/include/c++/4.9/bits/shared_ptr_base.h:880:2: note: template argument deduction/substitution failed:
/usr/include/c++/4.9/bits/shared_ptr_base.h:1001:4: note: mismatched types '_Tp1*' and 'std::__shared_ptr<C, (__gnu_cxx::_Lock_policy)2u>'
__shared_ptr(std::move(__r)).swap(*this);
^
/usr/include/c++/4.9/bits/shared_ptr_base.h:870:11: note: template<class _Tp1> std::__shared_ptr<_Tp, _Lp>::__shared_ptr(_Tp1*)
explicit __shared_ptr(_Tp1* __p)
^
/usr/include/c++/4.9/bits/shared_ptr_base.h:870:11: note: template argument deduction/substitution failed:
/usr/include/c++/4.9/bits/shared_ptr_base.h:1001:4: note: mismatched types '_Tp1*' and 'std::__shared_ptr<C, (__gnu_cxx::_Lock_policy)2u>'
__shared_ptr(std::move(__r)).swap(*this);
^
/usr/include/c++/4.9/bits/shared_ptr_base.h:865:17: note: constexpr std::__shared_ptr<_Tp, _Lp>::__shared_ptr() [with _Tp = D; __gnu_cxx::_Lock_policy _Lp = (__gnu_cxx::_Lock_policy)2u]
constexpr __shared_ptr() noexcept
^
/usr/include/c++/4.9/bits/shared_ptr_base.h:865:17: note: candidate expects 0 arguments, 1 provided
继承:
// enable_shared_from_this example
#include <iostream>
#include <memory>
struct C : std::enable_shared_from_this<C> {};
struct D : public C {};
int main () {
std::shared_ptr<D> foo;
foo = std::make_shared<D>();
std::shared_ptr<C> bar = foo->shared_from_this();
return 0;
}
你在class C
中定义了shared_from_this
:所以对象returnsstd::shated_ptr<C>
。没有惊喜。您仍然可以使用 std::dynamic_pointer_cast
.
std::shared_ptr<D>
正如@DimityKuzminov 已经指出的那样,shared_from_this()
将始终 return 一个 std::shared_pointer<C>
,当从 std::shared_ptr<D>
调用时也是如此。为了使用 std::dynmaic_pointer_cast
,你的基类还需要有一个像虚析构函数这样的虚函数(否则你的编译器会告诉你 source type is not polymorphic
)。这是一个例子:
// enable_shared_from_this example
#include <iostream>
#include <memory>
struct C : std::enable_shared_from_this<C> {
virtual ~C() = default;
};
template<typename T, typename U>
std::shared_ptr<T>
shared_from(const std::shared_ptr<U> &a)
{
return std::dynamic_pointer_cast<T>(a->shared_from_this());
}
struct D : public C {};
int main () {
std::shared_ptr<D> foo, bar;
foo = std::make_shared<D>();
bar = shared_from<D>(foo);
return 0;
}