Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 定义类模板构造函数的两种方法之间的差异_C++_Templates - Fatal编程技术网

C++ 定义类模板构造函数的两种方法之间的差异

C++ 定义类模板构造函数的两种方法之间的差异,c++,templates,C++,Templates,我正在尝试实现我的自定义版本的共享ptr和弱ptr。在实现它们的过程中,我遇到了一些问题 为了从构造函数中接受子类类型,我必须使用另一个模板类型U作为参数,而不是类“T”的模板类型 假设参数类型为U的构造函数为版本1 参数类型为T的构造函数为版本2 这是我的问题 为什么在我初始化相同类型的类模板时调用版本2 WeakPtr WeakPtr_a; WeakPtr WeakPtr_b=WeakPtr_a//对于版本1来说,这还不够吗? 在哪些情况下会调用版本2?这项实施是否可行 下面是我的

我正在尝试实现我的自定义版本的共享ptr和弱ptr。在实现它们的过程中,我遇到了一些问题

为了从构造函数中接受子类类型,我必须使用另一个模板类型U作为参数,而不是类“T”的模板类型

假设参数类型为U的构造函数为版本1 参数类型为T的构造函数为版本2

这是我的问题

  • 为什么在我初始化相同类型的类模板时调用版本2
WeakPtr WeakPtr_a;
WeakPtr WeakPtr_b=WeakPtr_a//对于版本1来说,这还不够吗?
  • 在哪些情况下会调用版本2?这项实施是否可行
下面是我的代码片段

WeakPtr十二月水电站

模板
类WeakPtr
{
T*m_objectPtr=nullptr;
SharedObjectInfo*m_SharedObjectInfo=nullptr;
模板
朋友级弱者;
公众:
constexpr WeakPtr();
~WeakPtr()=默认值;
//!复制构造函数
//!\t RAM U:要从中复制的weakPtr的模板类型
//!U必须与T的类型相同或T的子类相同,否则断言将失败
//!\param weakPtr:要从中复制的weakPtr
模板
WeakPtr(const WeakPtr&WeakPtr);//版本1
//!复制构造函数
//!\param weakPtr:要从中复制的weakPtr
WeakPtr(const WeakPtr&WeakPtr);//版本2
};
WeakPtr Impl.hpp

模板
模板
WeakPtr::WeakPtr(const WeakPtr&WeakPtr)
:m_objectPtr(weakPtr.m_objectPtr),
m_sharedObjectInfoPtr(weakPtr.m_sharedObjectInfoPtr)
{
静态断言(std::is_same::value)||
std::是_base _of::value);
}
模板
WeakPtr::WeakPtr(const WeakPtr&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}
   {  }
在版本1中添加了第二个未使用的参数,以允许选择版本1从版本2调用它

在版本2中的委托调用中观察
WeakPtr{WeakPtr,0}
中的零:添加的零强制版本1的调用,因为版本2只有一个参数


当类型不同时,默认值对于允许直接使用版本1非常重要。

如注释中所述,当提供精确的非模板构造函数(在您的情况下为版本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}
   {  }
在版本1中添加了第二个未使用的参数,以允许选择版本1从版本2调用它

在版本2中的委托调用中观察
WeakPtr{WeakPtr,0}
中的零:添加的零强制版本1的调用,因为版本2只有一个参数


当类型不同时,默认值对于允许直接使用版本1非常重要。

当多个函数都可以使用时,编译器会查找。规则4说非模板化版本比模板专门化更可取。@Raymond Chen您认为实现这一点的方法更好吗?我不想用模板参数类型声明两个版本的构造函数或方法。您可以通过委托给模板版本来实现非模板版本:
A(const A&b):A(b){}
。您应该保留这两个构造函数,因为常规副本构造函数不需要任何额外的验证。如果在初始化后要执行公共代码,则可以调用公共构造函数或初始化函数。或者,模板构造函数可以在执行
静态_cast
(和适当的检查)后转发到默认构造函数。当多个函数符合使用条件时,编译器将查找默认构造函数。规则4说非模板化版本比模板专门化更可取。@Raymond Chen您认为实现这一点的方法更好吗?我不想用模板参数类型声明两个版本的构造函数或方法。您可以通过委托给模板版本来实现非模板版本:
A(const A&b):A(b){}
。您应该保留这两个构造函数,因为常规副本构造函数不需要任何额外的验证。如果在初始化后要执行公共代码,则可以调用公共构造函数或初始化函数。或者,模板构造函数可以在
静态_cast
(和适当的检查)之后转发到默认构造函数,谢谢您给我建议了更好的方法!我试试这个谢谢你给我建议了更好的方法!我试试这个