【发布时间】:2020-04-09 17:01:59
【问题描述】:
考虑以下示例:
#include <memory>
template<class T>
class RefSP {
private:
std::shared_ptr<T> p;
public:
template<class A>
RefSP(A&& v) : p(std::forward<A>(p)) {}
};
template <
class T,
class U,
typename std::enable_if<std::is_base_of<std::shared_ptr<U>, T>::value>::type* = nullptr>
inline RefSP<U>*
make_ref_sp(T&& p)
{
return new RefSP<U>(std::forward<T>(p));
}
int main()
{
auto sp = std::make_shared<int>(42);
auto x = make_ref_sp(sp);
}
我得到编译错误
In function 'int main()':
25:28: error: no matching function for call to 'make_ref_sp(std::shared_ptr<int>&)'
25:28: note: candidate is:
17:1: note: template<class T, class U, typename std::enable_if<std::is_base_of<std::shared_ptr<_Tp2>, T>::value>::type* <anonymous> > RefSP<U> make_ref_sp(T&&)
17:1: note: template argument deduction/substitution failed:
25:28: note: couldn't deduce template parameter 'U'
问题是,我如何修复代码,以便在保留移动语义的同时推断出 T 是 std::shared_ptr<U>。
【问题讨论】:
-
if constexpr (std::is_specialization_v<T, std::shared_ptr>) {(或类似的)呢? -
1) 将 U 替换为
std::remove_cvref_t<T>。 2) 您是否尝试创建std::shared_ptr<std::shared_ptr<int>>?为什么?RefSP也需要修复。 -
所以当
T是std::shared_ptr<int>时,您希望U成为int?那么std::is_base_of是什么意思呢?永远是true。 -
在
RefSP的构造函数中执行RefSP(A&& v) : p(std::forward<A>(v))并尝试auto x = make_ref_sp(std::move(sp)) -
详细说明主要问题:您不会从 T 中推断出 U,而是将 T 转换为您想要的 U。您不能只要求编译器以通用方式推断 U - 如果您以推断 U 的方式编写类型和模板,例如证明费马定理?
标签: c++11 templates shared-ptr