我需要C ++数组类模板,这是固定大小,基于堆栈,不需要默认构造函数 [英] I need C++ array class template, which is fixed-size, stack-based and doesn't require default constructor

查看:163
本文介绍了我需要C ++数组类模板,这是固定大小,基于堆栈,不需要默认构造函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以,我一直在看boost :: array,但它需要默认的构造函数定义。
我认为用数据填充这个数组的最好方法是通过一个push_back(const T&)方法。调用它比SIZE多(在编译时已知)会导致assert或异常,这取决于构建配置。这样,它总是包含有意义的数据。
有人知道这个概念的高效,可移植,可靠的实现吗?

解决方案



你想要的是我自己梦寐以求的东西:a boost :: optional_array< T,N>



有两种变体:




  • 第一:类似于 boost :: array< boost :: optional ,N> ,即每个元素可以设置也可以不设置。

  • 第二:类似于 std :: vector< T> (以某种方式),即所有开始元素都被设置,并且所有后面的元素都不被设置。



鉴于以前的问题/意见,似乎你想要第二个,但它并不重要,因为两者都是相似的。

  template< typename T,size_t N> 
class stack_vector
{
public:
bool empty()const {return mSize == 0; }
size_t size()const {return mSize; }
size_t capability()const {return N; }
size_t max_size()const {return N; }

T& operator [](size_t i){return *(this-> pfront()+ i); }
/// ...

private:
T * pfront()const {return reinterpret_cast< T *>(& mStorage); }

std :: aligned_storage< N * sizeof(T),alignof(T) mStorage;
size_t mSize; //表示设置了多少个元素,从开始
};让我们专注于这些非常特殊的操作:


pre> template< typename T,size_t N>
void push_back(T const& t)
{
new(this-> pfront()+ mSize)T(t); // in place construction
++ mSize;
}

template< typename T,size_t N>
void clear()
{
for(size_t i = 0; i!= mSize; ++ i)
{this-> pfront + i)→T();
}
mSize = 0;
}

你可以注意到,主要的困难是记住:




  • 如果尚未创建任何元素,则需要放置新的+副本构造而不是赋值。




在传统的STL容器上有很多操作可能很难实现。在向量,元素混排(由于插入擦除



也请注意,使用C ++ 0x和初始化列表向量获取 emplace_back 直接构造一个元素,从而解除 CopyConstructible 的要求,可能是一个很好的依赖于你的。


So, I've been looking at boost::array but it does require default constructor defined. I think the best way of filling this array with data, would be through a push_back(const T&) method. Calling it more times than SIZE (known at compile-time) would result in assert or exception, depending on build configuration. This way it would always contain meaningful data. Does anyone know efficient, portable, reliable implementation of this concept?

解决方案

Well, I would have thought that someone would have brought the answer now, however it seems not, so let's go.

What you are wishing for is something I have myself dreamed of: a boost::optional_array<T,N>.

There are two variants:

  • First: similar to boost::array< boost::optional<T>, N >, that is each element may or may not be set.
  • Second: similar to a std::vector<T> (somehow), that is all beginning elements are set and all following ones are not.

Given the previous questions / comments, it seems you would like the second, but it doesn't really matter as both are quite alike.

template <typename T, size_t N>
class stack_vector
{
public:
  bool empty() const { return mSize == 0; }
  size_t size() const { return mSize; }
  size_t capacity() const { return N; }
  size_t max_size() const { return N; }

  T& operator[](size_t i) { return *(this->pfront() + i); }
  /// ...

private:
  T* pfront() const { return reinterpret_cast<T*>(&mStorage); }

  std::aligned_storage< N * sizeof(T), alignof(T) > mStorage;
  size_t mSize; // indicate how many elements are set, from the beginning
};

Let's focus on those very special operations:

template <typename T, size_t N>
void push_back(T const& t)
{
  new (this->pfront() + mSize) T(t); // in place construction
  ++mSize;
}

template <typename T, size_t N>
void clear()
{
  for (size_t i = 0; i != mSize; ++i)
  {
    (this->pfront() + i)->~T();
  }
  mSize = 0;
}

As you can notice, the main difficulty is to remember that:

  • if no element has been built there yet, you need placement new + copy construction instead of assignment.
  • elements that become "obsolete" (ie would be after the last element) should be properly disposed of (ie their destructor be invoked).

There are many operations on traditional STL container that may be tricky to implement. On a vector, element shuffling (due to insert or erase) are perhaps the most stricking examples.

Also note that with C++0x and initializer-lists vector get emplace_back to directly construct an element in place, thus lifting the CopyConstructible requirement, might be a nice boon dependent on your case.

这篇关于我需要C ++数组类模板,这是固定大小,基于堆栈,不需要默认构造函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆