我使用以下输入命令在Coliru中探讨了这个主题:
g++ -std=c++14 -O2 -Wall -pedantic -pthread main.cpp && ./a.out
测试代码可以在这里找到,但我已经将代码贴在下面。我在示例中使用了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上寻找答案,但只找到了对于实现std::shared_ptr没有特化的参考文献,这主要是因为没有人就该问题向标准委员会提出适当的建议。我很好奇,因为我会解释第4个重载的operator=,
std::shared_ptr<T[]>.operator=(std::unique_ptr<T[], Deleter>&&)
在cppreference上表明这种语法是合法的——无论std::shared_ptr的数组类型是否有特化,T[]和T[]都是相同的类型。此外,这种语法似乎仅适用于std::make_unique<T[]>的产物,而不适用于唯一指针对象,这与我的理解相矛盾——难道这些调用不应该是有效的吗?我期望它们之间唯一的区别是第一种情况下函数调用后无效的std::unique_ptr<T[]>。另外,我假设既然存在一种将动态分配的数组构造为shared_ptr的方法,不需要使用new,那么我应该优先选择它,而不是使用更混乱和异常不安全的new T[N]调用吗?简而言之:
1.operator=在std::shared_ptr<T[]>和std::unique_ptr<T[]>之间根本不起作用,尽管我期望它能够工作。为什么?
2.如果有的话,我会期望从T[]到T的类型转换是唯一指针和共享指针之间编译错误的来源。为什么这能行?
3.operator=在std::shared_ptr<T>和std::make_unique<T[]>之间可以工作,但对于std::unique_ptr<T[]>却无法工作。为什么?
4.在需要动态分配的共享数组的情况下,但我不想使用boost或vector(原因如下),我是否应该调用operator= std::make_unique<T[]>(N)?
为什么我不使用?
- Boost: 我的公司尚未批准使用Boost,我不知道何时或是否会获得批准使用它。
- Arrays: 我必须在运行时确定此数组的大小。
- Vectors: 我正在处理实时信号处理系统,并希望避免额外的指针解除引用。我也试图避免在头文件中包含不必要的库(这是用于读写子系统之间的通信)。然而,如果重要的话,我最终选择了稍后优化(过早优化...)并咬紧牙关。不过问题仍然存在。
std::shared_ptr
不支持数组。 - T.C.std::shared_ptr
主动不支持数组?我曾经以为缺乏特化意味着它会像处理其他任何类型一样处理数组类型。 - jaggedSpire