【问题标题】:Constant-sized vector恒定大小的向量
【发布时间】:2012-06-23 11:19:03
【问题描述】:

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

例如,而不是定义

std::vector<int>

会的

std::vector<10, int>

它应该是完全跨平台的。也许是一个开源类?

【问题讨论】:

    标签: c++ stl vector


    【解决方案1】:

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

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

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

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

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

    【讨论】:

    • 如果它是某个用户定义类型的向量并被赋予了初始大小,它会被初始化成什么?
    • 应该接受下面说使用 std::array 的答案
    • 我来这里是为了寻找这个答案。这个问题看起来很像有人在寻找std::array,但我在编译时不知道我的大小,并且只想分配固定数量的元素。
    【解决方案2】:

    没有办法定义一个恒定大小的向量。如果您在编译时知道大小,则可以使用 C++11 的 std::array 聚合。

    #include <array>
    
    std::array<int, 10> a;
    

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

    #include <tr1/array>
    
    std::tr1::array<int, 10> a;
    

    boost::array,正如其他答案中所建议的那样。

    【讨论】:

    • 尽管注意arrayvector 的不同之处在于数据包含在对象中。对于 10 个整数,您可能永远不会注意到差异,但对于大型数组,您可能(例如)注意到它们没有 O(1) swap,而大向量有。
    • 另外请注意,数组没有 sizecapacity 的概念,就像向量一样。在数组中size == max_size。也就是说,您不能创建大小为 10 的数组(即:10 个可能元素的空间),但只能填充 5 个并期望 size 返回 5。
    • 还要注意 std::array 不会转换为通用运行时大小。如果要将不同大小的数组传递给函数,则必须同时传入 data() 和 size()
    • @SteveLorimer "... 但是对于大型数组,您可能(例如)注意到它们没有 O(1) 交换,而大型向量却有。" - - 您能否分享我可以查看的资源/参考资料以了解更多信息?提前谢谢!
    • @Milan 对于一个向量,你只交换指向底层数组的指针,而除非数组是在堆上分配的(从而允许你只交换指向数组的指针),否则你必须移动所有要素。在此处阅读更多信息:stackoverflow.com/a/26312602/955273
    【解决方案3】:

    如果您想要一个固定的编译时指定大小(ala std::array&lt;T, N&gt;),但您希望能够用 0N 之间的不同数量的元素填充向量,那么一个不错的选择是 @ 987654321@.

    std::vector:

    std::vector 的大小是动态的 - 它会动态分配所需的存储空间,您不能限制大小并强制出错。

    但是,您可以reserve 某个大小,然后在需要分配新存储之前将元素添加到该大小。

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

    std::array:

    std::array 的大小是一个编译时常量 - 它会静态分配所需的存储空间,您无法更改大小。

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

    eastl::fixed_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

    【讨论】:

      【解决方案4】:

      使用std::array

      为了更好的可读性,您可以使用 typedef:

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

      【讨论】:

      • 当然,既然我们在写 C++11,我们就写using MyIntArray = std::array&lt;int, 10&gt;;
      • 这是假设在编译时大小是已知的。
      【解决方案5】:

      这是一个老问题,但如果有人只需要 在运行时定义大小的常量索引容器,我喜欢使用 unique_ptr

      // c++14
      auto constantContainer = std::make_unique<YourType []> ( size );
      
      // c++11
      std::unique_ptr<YourType[]> constantContainer {new YourType[ size ]};
      
      
      // Access
      constantContainer[ i ]
      

      【讨论】:

      • 你可以为 C++11 添加一个解决方案吗?另外,唯一指针的性能是否与向量相同?
      • 是的,两者都只有下面的普通缓冲区。
      • 嗯,这将是不可复制的,不是吗?
      【解决方案6】:

      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;
      

      【讨论】:

        【解决方案7】:

        这----> std::vector&lt;10, int&gt; 无效并导致错误。但是新的 C++ 标准引入了一个新的类;标准::数组。你可以像这样声明一个数组:

        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/找到更多关于这个课程的信息。

        【讨论】:

          【解决方案8】:

          如果您需要现代 c++ 功能以及多态性,您可以这样做

          template <typename T, unsigned N>
          struct polymorphic_std_array : std::array<T, N>, std::span<T>
          {
              polymorphic_std_array(std::array<T,N> a)
                  : std::array<T, N>(a)
                  , std::span<T>(*static_cast<std::array<T, N>*>(this))
              {}
          };
          
          int main()
          {
              std::span<int>* p = new polymorphic_std_array<int, 2>({ 1,2 });
              for (const auto& e : *p)
              {
                  std::cout << e << std::endl;
              }
          }
          

          【讨论】:

            猜你喜欢
            • 2011-03-27
            • 2020-07-31
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2019-04-22
            • 1970-01-01
            相关资源
            最近更新 更多