我认为 std::shared_ptr<T>
的 https://en.cppreference.com/w/cpp/memory/shared_ptr/shared_ptr 应该声明为
template< class T, class Y >
shared_ptr<T>( const shared_ptr<Y>& r, element_type* ptr ) noexcept;
以外
template< class Y >
shared_ptr( const shared_ptr<Y>& r, element_type* ptr ) noexcept;
对不起,我的英语很差,https://godbolt.org/z/991PEzzjE可能会使您的问题更清楚:
#include<memory>
#include<vector>
struct Widget
{
std::vector<int> vec;
int var;
};
int main()
{
auto wp{std::make_shared<Widget>(std::vector<int>{1,2,3}, 69)};
std::shared_ptr<std::vector<int>> vp{wp, &wp->vec};
}
你看,vp
是 std::shared_ptr<vector<int>>
,而 wp
是 std::shared_ptr<Widget>
。所以,我认为上述构造函数的声明应该是 template< class T, class Y >
而不是 shared_ptr<Y>
。
补充:为什么我要对上述声明进行这样的修改?我只想强调,构造的别名构造函数的类型(即 shared_ptr<T>
)与作为参数传递的对象不同。 (即参数的类型是 shared_ptr<Y>
)。
注意:根据 https://en.cppreference.com/w/cpp/memory/shared_ptr/shared_ptr,第 8 个构造函数在 C++11
中可用,但上面的代码 sinppet 似乎无法使用 C++11
编译,所以我必须将编译选项设置为C++20
。并且这篇文章的标签仍然是 C++11
,而不是笔误。如果我错了,请告诉我。
回答1
类 std::shared_ptr<T>
已经有 typename T
,并且 typename Y
将别名构造函数作为模板函数:
namesapce std
{
template <typename T>
class shared_ptr
{
template<typename Y>
shared_ptr( const shared_ptr<Y>& r, element_type* ptr ) noexcept;
}
}