C++ 了解独特的ptr和x27;s构造函数,该构造函数接受自定义删除程序 我在说什么
我所指的覆盖图是3和4,具有以下签名:C++ 了解独特的ptr和x27;s构造函数,该构造函数接受自定义删除程序 我在说什么,c++,templates,c++17,unique-ptr,type-deduction,C++,Templates,C++17,Unique Ptr,Type Deduction,我所指的覆盖图是3和4,具有以下签名: unique_ptr(指针p,/*见下文*/d1)无异常; 我的问题 主要包括: /*见下文*/的解释实际上是什么意思 作为一名程序员,在选择将什么作为deleter类型模板参数传递给std::unique_ptr时,如何利用它 但更详细地说: std::unique_ptr的构造函数是模板化的,这是必须提供deleter模板参数的原因吗 如果前面问题的答案是肯定的,那么如果通过从链接页面中的类模板参数推断选择了这两个构造函数中的任何一个,那么程序
unique_ptr(指针p,/*见下文*/d1)无异常;
我的问题
主要包括:
的解释实际上是什么意思/*见下文*/
- 作为一名程序员,在选择将什么作为deleter类型模板参数传递给
时,如何利用它std::unique_ptr
的构造函数是模板化的,这是必须提供deleter模板参数的原因吗std::unique_ptr
- 如果前面问题的答案是肯定的,那么如果通过从链接页面中的类模板参数推断选择了这两个构造函数中的任何一个,那么程序格式错误的句子是什么意思
和\u Dp
实际上有什么区别,这有什么重要意义\u Del
std::unique_ptr
,所有都是强制性的(即没有=默认_type_或_值
)模板类的模板参数必须通过
提供
此外,在/usr/include/c++/10.2.0/bits/unique_ptr.h
中,我或多或少看到了这一点:
名称空间std{
// …
模板
类唯一\u ptr{
公众:
// …
使用deleter\u type=\u Dp;
// …
模板
唯一的\u ptr(指针u p,常量deleter_类型&\uu d)无例外:_M_t(u p,u d){
// …
}
// …
}
其中,构造函数在类型参数\u Del
上模板化,该参数默认为类“deleter\u type
(它是\u Dp
的别名);由此我了解到,如果我错了,请纠正我(*),std::unique_ptr
甚至不能利用C++17对类的模板类型推断,因此就重载而言,\u Dp
的模板参数仍然是强制的(即,如果要将deleter对象作为第二个参数传递给构造函数)
既然如此,我们传递给std::unique\u ptr
的实际类型参数可以使用引用声明符进行修饰,如链接页面中所述。但这就是我迷失的地方,更不用说我确实看到通常\u Dp
和\u Del
可以不同(例如,它们可能因引用声明者的不同而不同),这使我的理解更加复杂
但是,我将复制页面中解释各种可能场景的部分:
3-4)构造一个std::unique_ptr
对象,该对象拥有p
,使用p
初始化存储指针,并初始化删除器D
,如下所示(取决于D
是否为引用类型)
- a) 如果
为非参考类型D
,则签名为:a
unique_ptr(pointer p, const A& d) noexcept; unique_ptr(pointer p, A&& d) noexcept;
unique_ptr(pointer p, A& d) noexcept; unique_ptr(pointer p, A&& d) = delete;
unique_ptr(pointer p, const A& d) noexcept; unique_ptr(pointer p, const A&& d) = delete;
- b) 如果
是左值引用类型D
,则签名为:A&
unique_ptr(pointer p, const A& d) noexcept; unique_ptr(pointer p, A&& d) noexcept;
unique_ptr(pointer p, A& d) noexcept; unique_ptr(pointer p, A&& d) = delete;
unique_ptr(pointer p, const A& d) noexcept; unique_ptr(pointer p, const A&& d) = delete;
- c) 如果
是左值引用类型D
,则签名为:const A&
unique_ptr(pointer p, const A& d) noexcept; unique_ptr(pointer p, A&& d) noexcept;
unique_ptr(pointer p, A& d) noexcept; unique_ptr(pointer p, A&& d) = delete;
unique_ptr(pointer p, const A& d) noexcept; unique_ptr(pointer p, const A&& d) = delete;
std::forward(d)
初始化的。只有当std::is_constructible::value
为true
时,这些重载才参与重载解析
我能解释引用的文本的唯一方法是如下,带着很多疑问
- 如果我们想将deleter
作为参数传递给构造函数,我们必须明确地将ad
作为模板参数传递给。。。什么?到d
类和/或它的构造函数?甚至可以将模板参数传递给构造函数吗
可以有三种D
- 如果我们将其指定为
,这意味着我们希望能够将A(可能是A
)左值或右值传递为const
,这样就定义了取d
和const A&
的两个重载A&
- 如果我们将其指定为
,这意味着我们希望不能将右值作为常量a&
传递,因此使用d
的重载将被删除,因为它将绑定到右值,而使用a&
的重载,因为后者也将绑定到右值常量a&
- 如果我们将其指定为
,这意味着我们希望能够将左值或右值同时传递为常量a&
,因此选择使用d
的重载,而使用常量a&
的重载是常量a&
删除,因为该参数类型无法绑定到左值,它对待右值的方式与
的方式没有什么不同,正如答案中所解释的,最重要的是,它绑定到右值,防止另一个重载常量A&
绑定到右值,这将导致悬挂引用存储在常量A&
中(原因如下)std::unique\u ptr
- 但是,1的不同用例是什么。三,。当右值作为
传递时?1.将其绑定到d
和3。将它绑定到A&
,这样前者可以窃取资源,而后者则不能常量A&