定义类模板构造函数的两种方法之间的区别
Difference between two ways of defining class template constructors
我正在尝试实现我的自定义版本的shared_ptr和weak_ptr。在实现它们时,我遇到了一些问题。
为了接受来自构造函数的子类类型,我不得不使用另一个模板类型 U 作为参数,而不是类 'T' 的模板类型。
假设参数类型为 U 的构造函数为版本 1 和参数类型 T 作为版本 2 的构造函数
这是我的问题
- 为什么当我使用相同类型初始化类模板时会调用版本 2?
WeakPtr<T> weakPtr_a;
WeakPtr<T> weakPtr_b = weakPtr_a; //Shouldn't this be still enough with version 1?
- 在哪些情况下会调用版本 2?这种实现可行吗?
这是我的代码片段
WeakPtr-Decl.hpp
template <typename T>
class WeakPtr
{
T* m_objectPtr = nullptr;
SharedObjectInfo* m_sharedObjectInfoPtr = nullptr;
template <typename U>
friend class WeakPtr;
public:
constexpr WeakPtr();
~WeakPtr() = default;
//! Copy constructor
//! tparam U : template type of weakPtr to copy from
//! U must be same type as T or subclass of T or assertion will fail
//! param weakPtr : weakPtr to copy from
template <typename U>
WeakPtr(const WeakPtr<U>& weakPtr); // Version 1
//! Copy constructor
//! param weakPtr : weakPtr to copy from
WeakPtr(const WeakPtr<T>& weakPtr); // Version 2
};
WeakPtr-Impl.hpp
template <typename T>
template <typename U>
WeakPtr<T>::WeakPtr(const WeakPtr<U>& weakPtr)
: m_objectPtr(weakPtr.m_objectPtr),
m_sharedObjectInfoPtr(weakPtr.m_sharedObjectInfoPtr)
{
static_assert(std::is_same<std::decay_t<T>, std::decay_t<U>>::value ||
std::is_base_of<std::decay_t<T>, std::decay_t<U>>::value);
}
template <typename T>
WeakPtr<T>::WeakPtr(const WeakPtr<T>& weakPtr)
: m_objectPtr(weakPtr.m_objectPtr),
m_sharedObjectInfoPtr(weakPtr.m_sharedObjectInfoPtr)
{
}
如注释中所述,当可用的确切非模板构造函数(版本 2,在您的情况下(时,它优先于模板构造函数(版本 1(。
我建议使用委托构造函数,所以让编译器选择版本 2(当类型相同时(,并从版本 2 调用版本 1。
我建议在版本 1 中添加一个未使用的默认第二个参数
template <typename U> // ............VVVVVVV
WeakPtr (WeakPtr<U> const & weakPtr, int = 0)
: m_objectPtr{weakPtr.m_objectPtr},
m_sharedObjectInfoPtr{weakPtr.m_sharedObjectInfoPtr}
{ }
并按如下方式转换版本 2
WeakPtr (WeakPtr const & weakPtr) : WeakPtr{weakPtr, 0}
{ }
添加了版本 1中第二个未使用的参数,以允许选择从版本 2 调用的版本 1。
观察版本 2中委派调用时WeakPtr{weakPtr, 0}
中的零:添加的零强制调用版本 1,因为版本 2 只有一个参数。
默认值对于允许在类型不同时直接使用版本 1 非常重要。
相关文章:
- 定义类模板构造函数的两种方法之间的区别
- 初始化类的两种方法?
- 在没有堆的情况下用两种方法构造对象
- 解决虚拟方法的歧义继承的两种方法
- 这两种方法有什么区别?
- 确保派生的类实现至少是来自抽象类(C )的两种方法之一
- 动态分配一维结构数组:两种方法
- 初始化`rand()的两种方法
- 分配std :: vector元素的两种方法
- 同步QT中两种方法的螺纹执行
- 这两种方法有什么区别
- 关于链表,这两种方法有什么不同?C++中的1个自变量与2个自变量
- 我可以将这两种方法/函数合二为一吗?
- 如何减少googletest的详细程度(覆盖默认侦听器的两种方法)
- 就百分比而言,这两种方法之间的平均性能差异有多大
- 在C++中抛出异常的两种方法(不使用堆)
- 将两种方法组合在一起
- 以下两种方法在 c++ 中有什么区别
- 使用两种方法重写<<运算符
- 函数指针实现的两种方法之间的差异