I want to implement std::end for unique pointer. The problem is that I have to get N(count of elements in array).
1.Approach deduce type from template
template <typename T, size_t N>
T* end(const unique_ptr<T[N]> &arr)
{
return arr.get() + N;
}
But I got error error: C2893: Failed to specialize function template 'T *test::end(const std::unique_ptr> &)' with [ _Ty=T [N] ] With the following template arguments: 'T=int' 'N=0x00'
It looks like It is not possible to deduce N
2.Get N from allocator. Allocator has to know N to correctly execute delete[]. You could read about this in this article. There are two approaches:
Over-allocate the array and put n just to the left.
Use an associative array with p as the key and n as the value.
The problem is how to get this size cross platform/compiler.
Maybe someone knows better approaches or know how to make this works?
答案 0 :(得分:8)
If you have a run time sized array and you need to know the size of it without having to manually do the book keeping then you should use a std::vector
. It will manage the memory and size for you.
std::unique_ptr<T[]>
is just a wrapper for a raw pointer. You cannot get the size of the block the pointer points to from just the pointer. The reason you use a std::unique_ptr<T[]>
over T* foo = new T[size]
is the unique_ptr
makes sure delete[]
is called when the pointer goes out of scope.
答案 1 :(得分:0)
这样的东西?
template<class X>
struct sized_unique_buffer;
template<class T, std::size_t N>
struct sized_unique_buffer<T[N]>:
std::unique_ptr<T[]>
{
using std::unique_ptr<T[]>::unique_ptr;
T* begin() const { return this->get(); }
T* end() const { return *this?begin(*this)+N:nullptr; }
bool empty() const { return N==0 || !*this; }
};
我们有一个编译时未执行的固定编译时长度的承诺。
类似的设计可以用于动态运行时长度。
在某些编译器中,当您致电T
时,T
可以轻易销毁new T[N]
的数量。系统可以自由地过度分配并为您提供更大的缓冲区(即,为了大分配而舍入到页边界,或者通过分配缓冲区的位置隐式存储缓冲区的大小,以减少开销和舍入分配),所以分配大小不需要与元素数完全匹配。
对于非平凡的被破坏的T
,编译器必须知道要从指针中销毁多少。此信息不会暴露给C ++。
您可以手动分配缓冲区和计数,并使用自定义删除程序将其传递给unique_ptr
,即使是无状态删除程序。这将允许类型
unique_buffer<T[]> ptr;
您可以在适当的运行时间内获得元素数量。
如果您将长度存储在删除器中,则可以在更大的unique_buffer<T[]>
代价的环路限制(保存缓存未命中)上获得更多位置。
以便携式方式无法使用纯粹的unique_ptr<T[]>
执行此操作。