std::end for unique_ptr<t[]>

时间:2016-10-20 13:16:41

标签: c++ c++11

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:

  1. Over-allocate the array and put n just to the left.

  2. 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?

2 个答案:

答案 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[]>执行此操作。