我使用以下输入命令在Coliru中探讨了这个主题:
g++ -std=c++14 -O2 -Wall -pedantic -pthread main.cpp && ./a.out
Run Code Online (Sandbox Code Playgroud)
测试可以在这里找到,但我已经发布了下面的代码.我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";
}
Run Code Online (Sandbox Code Playgroud)
我在SO上寻找答案,但只是提到std::shared_ptr没有专业化的实施,这主要是因为没有人费心向标准委员会提出有关该主题的正确建议.
我很好奇,因为我会解释第四次重载operator=,std::shared_ptr<T[]>.operator=(std::unique_ptr<T[], Deleter>&&)在cppreference上表示这样的语法是合法的 - T[]并且T[]无论数组类型的特化状态如何都是相同的类型std::shared_ptr.
此外,这种语法似乎只适用于产品std::make_unique<T[]>,而不是唯一的指针对象,这违背了我对该主题的理解 - 不应该调用实际上是相同的,尽管移动现有对象,而另一个好吧,移动刚刚创建的对象?我希望它们之间的唯一区别是std::unique_ptr<T[]>在第一种情况下函数调用后的无效.
作为旁注,我假设因为有一种方法可以将动态分配的数组构建成一个shared_ptr不需要使用的方法new,我应该更喜欢它的乱码和异常不安全的调用new T[N]?
TL;博士:
operator=虽然我希望它可以工作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)?我为什么不用?
§20.8.2.2.1/ 28:
Run Code Online (Sandbox Code Playgroud)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[]>的T*是U(*)[],并且U*无法转换为U(*)[],因此从不考虑过载.
| 归档时间: |
|
| 查看次数: |
379 次 |
| 最近记录: |