我使用以下输入命令在Coliru中探讨了这个主题:
g++ -std=c++14 -O2 -Wall -pedantic -pthread main.cpp && ./a.out
可以找到here的测试,但我已经发布了以下代码。我在我的示例中使用了int
,因为它是基本类型。
#include <iostream>
#include <memory>
struct Foo{
Foo() :
a_{0}, b_{1}, c_{-1}, combination_{0.5} {}
int
a_,
b_,
c_;
double
combination_;
};
int main()
{
//int
// *unManagedArray = new int[16];
std::unique_ptr<int[]>
uniqueArrayOrigin = std::make_unique<int[]>(16);
std::shared_ptr<int>
// works but needs call to new
// sharedSingleTest{unManagedArray, std::default_delete<int[]>{}};
// works, does not require call to new
sharedSingleUnique = std::make_unique<int[]>(16);
// compilation error (conversion to non-scalar type)
// sharedSingleDerived = uniqueArrayOrigin;
// std::shared_ptr<int[]>
// compilation errors
// sharedArrayTest{unManagedArray, std::default_delete<int[]>{}};
// compilation error (conversion to non-scalar type)
// sharedArrayUnique = std::make_unique<int[]>(16);
// compilation error (conversion to non-scalar type)
// sharedArrayDerived = uniqueArrayOrigin;
std::shared_ptr<Foo>
// works: specified overload of operator= for shared_ptr
nonArrayTest = std::make_unique<Foo>();
std::cout << "done!\n";
}
我已经在SO上寻找答案,但只是references向std::shared_ptr
执行operator=
而没有专业化,而这主要是因为没有人费心去提出适当的建议关于这个问题的标准委员会。
我很好奇,因为我会在cppreference上解释T[]
,std::shared_ptr<T[]>.operator=(std::unique_ptr<T[], Deleter>&&)
的第4次重载,以表明此类语法合法 - T[]
和std::shared_ptr
相同毕竟,无论std::make_unique<T[]>
的数组类型的特化状态如何,都要输入。
此外,这种语法似乎只适用于std::unique_ptr<T[]>
的产品,而不是一个独特的指针对象,这违背了我对该主题的理解 - 不应该调用实际上是相同的,尽管一个移动现有对象,另一个移动刚刚创建的对象?我希望它们之间的唯一区别是在第一种情况下函数调用之后的无效shared_ptr
。
作为旁注,我假设由于有一种方法可以将动态分配的数组构建到new
中,而不需要使用new T[N]
,我应该更喜欢它。和operator=
的异常不安全调用?
TL; DR:
std::shared_ptr<T[]>
在std::unique_ptr<T[]>
和T[]
之间根本不起作用,但我希望它可以正常工作。为什么?T
到operator=
的类型转换成为唯一和共享指针之间的编译错误的来源。为什么这样做?std::shared_ptr<T>
适用于std::make_unique<T[]>
和std::unique_ptr<T[]>
,但不适用operator= std::make_unique<T[]>(N)
。为什么?manage_reportUserPermissions
?为什么我不使用?
答案 0 :(得分:5)
§20.8.2.2.1/ 28:
template <class Y, class D> shared_ptr(unique_ptr<Y, D>&& r);
备注:此构造函数不应参与重载解析 除非
unique_ptr<Y, D>::pointer
可转换为T*
。
但是,unique_ptr<U[]>::pointer
实际上是U*
,而shared_ptr<U[]>
的{{1}}是T*
;并且U(*)[]
无法转换为U*
,因此永远不会考虑重载。