恒定大小的矢量

有人知道定义常量向量的方法吗?

例如,不定义

std::vector<int>

会的

std::vector<10, int>

它应该是完全跨平台的

119907 次浏览

使用 数组

为了提高可读性,可以使用 typedef:

typedef std::array<int, 10> MyIntArray;

无法定义一个常数大小的向量。如果您知道编译时的大小,您可以使用 C + + 11的 数组聚合。

#include <array>


std::array<int, 10> a;

如果你没有相关的 C + + 11支持,你可以使用 TR1版本:

#include <tr1/array>


std::tr1::array<int, 10> a;

数组,正如在其他答案中所建议的那样。

std::vector是一个动态容器,没有限制其增长的机制。分配初始大小:

std::vector<int> v(10);

C + + 11有一个更合适的 std::array:

std::array<int, 10> my_array;

如果您的编译器不支持 C + + 11,可以考虑使用 boost::array:

boost::array<int, 10> my_array;

此—— > std::vector<10, int>无效并导致错误。但是新的 C + + 标准引入了一个新类: std: : array。可以像下面这样声明一个数组:

std::array<int, 5> arr; // declares a new array that holds 5 ints
std::array<int, 5> arr2(arr); // arr2 is equal to arr
std::array<int, 5> arr3 = {1, 2, 3, 4, 5}; // arr3 holds 1, 2, 3, 4, 5

std::array的大小不变,支持 iterator/const_iterator/reverse_iterator/const_reverse_iterator。你可以在 http://cplusplus.com/reference/stl/array/找到更多关于这个类的信息。

向量总是可以动态增长,但是有两种方法可以分配初始大小:

这将分配初始大小并用零填充元素:

std::vector<int> v(10);
v.size(); //returns 10

这将分配一个初始大小,但不用零填充数组:

std::vector<int> v;
v.reserve(10);
v.size(); //returns 0

如果您想要一个固定的编译时指定的大小(ala std::array<T, N>) ,但是您希望能够在 0N之间用不同数量的元素填充向量,那么一个好的选择是 eastl::fixed_vector

性传播疾病:

std::vector的大小是动态的——它将动态分配所需的存储空间,而且您不能限制大小并强制执行错误。

然而,您可以 reserve一定的大小,然后添加元素之前,需要分配新的存储大小。

vector.size()最初为0,随着元素的添加而增加

数组:

std::array的大小是一个编译时常数——它会静态地分配所需的存储空间,而且你不能改变它的大小。

array.size()始终是数组的大小,等于 array.max_size()

: fix _ Vector:

eastl::fixed_vector的大小可以是静态的,也可以是动态的。

它最初将分配一定数量的元素,然后如果允许动态增长,将根据需要动态分配。

对于您最初要求的目的,您可以禁用成长(通过下面模板实例中的 bEnableOverflow)

fixed_vector.size()最初为0,并随着添加元素而增加。

template<typename T,
size_t nodeCount,
bool bEnableOverflow = true,
typename OverflowAllocator =
typename eastl::type_select<bEnableOverflow,
EASTLAllocatorType,
EASTLDummyAllocatorType>::type>
class fixed_vector;

举个简单的例子:

#include <iostream>
#include <vector>
#include <array>
#include "EASTL/fixed_vector.h"


int main()
{
std::vector<int> v;
v.reserve(10);
std::cout << "size=" << v.size() << " capacity=" << v.capacity() << '\n';


std::array<int, 10> a;
std::cout << "size=" << a.size() << " capacity=" << a.max_size() << '\n';


eastl::fixed_vector<int, 10, false> fv;
std::cout << "size=" << fv.size() << " capacity=" << fv.capacity() << '\n';


return 0;
}

产出:

size=0 capacity=10
size=10 capacity=10
size=0 capacity=10

请注意,array的大小是10,而 vectorfixed_vector的大小是0

这是一个老问题,但如果有人只是需要 具有在运行时定义的大小的恒定大小索引容器,我喜欢使用 Unique _ ptr:

// c++14
auto constantContainer = std::make_unique<YourType []> ( size );


// c++11
std::unique_ptr<YourType[]> constantContainer {new YourType[ size ]};




// Access
constantContainer[ i ]

改进帕里的答案
多年来,我一直使用下面这个类 来处理数字计算应用程序:

inline void nodeleter(void*) {}


/// Array of T with ownership. Like \see std::unique_ptr<T[]> but with size tracking.
/// @tparam T Element type.
template <typename T>
class unique_array : public std::unique_ptr<T[],void (*)(void*)>
{   size_t Size;
private:
typedef std::unique_ptr<T[],void (*)(void*)> base;
protected:
unique_array(T* ptr, size_t size, void (*deleter)(void*)) noexcept : base(ptr, deleter), Size(size) {}
void reset(T* ptr, size_t size) noexcept { base::reset(ptr); Size = size; }
public:
constexpr unique_array() noexcept : base(nullptr, operator delete[]), Size(0) {}
explicit unique_array(size_t size) : base(new T[size], operator delete[]), Size(size) {}
template <size_t N> unique_array(T(&arr)[N]) : base(arr, &nodeleter), Size(N) {}
unique_array(unique_array<T>&& r) : base(move(r)), Size(r.Size) { r.Size = 0; }
void reset(size_t size = 0) { base::reset(size ? new T[size] : nullptr); Size = size; }
void swap(unique_array<T>&& other) noexcept { base::swap(other); std::swap(Size, other.Size); }
void assign(const unique_array<T>& r) const { assert(Size == r.Size); std::copy(r.begin(), r.end(), begin()); }
const unique_array<T>& operator =(const unique_array<T>& r) const { assign(r); return *this; }
size_t size() const noexcept { return Size; }
T* begin() const noexcept { return base::get(); }
T* end() const noexcept { return begin() + Size; }
T& operator[](size_t i) const { assert(i < Size); return base::operator[](i); }
unique_array<T> slice(size_t start, size_t count) const noexcept
{   assert(start + count <= Size); return unique_array<T>(begin() + start, count, &nodeleter); }
};
  • 赋值是可能的 但是这个 不能改变大小(尽管它很容易实现)。
  • 您可以使用 通过调用 reset改变大小,但是顾名思义,它会丢弃任何数据。
  • 支持 Move 语义
  • const实例不使其内容 const。只有 储藏室不能更改。
  • 它还限制了不属于实例的 切片支架。但他们没有终身管理。你需要自己关心那些悬而未决的推荐信。
  • 缺少一些与 C + + Container要求完全兼容的特性,首先是 typedef。到目前为止我都不需要它们。
  • 很容易为数值类型扩展此类型并添加进一步的向量操作。但是没有直接的自动性,因为至少 std::is_arithmetic<std::complex<double>>::value是错误的。