为什么 std::array 需要大小作为模板参数而不是构造函数参数?

ruf*_*uff 5 c++ std c++11 stdarray

我发现了很多设计问题,特别是传递std::array<>给函数时。基本上,当您初始化 std::array 时,它会接受两个模板参数<class T和size_t size>。但是,当您创建需要 和 的函数时std::array,我们不知道大小,因此我们还需要为函数创建模板参数。

template <size_t params_size> auto func(std::array<int, params_size> arr);
Run Code Online (Sandbox Code Playgroud)

为什么不能std::array在构造函数中获取大小?(IE):

auto array = std::array<int>(10);
Run Code Online (Sandbox Code Playgroud)

那么这些函数看起来就不那么激进了,并且不需要模板参数,如下所示:

auto func (std::array<int> arr);
Run Code Online (Sandbox Code Playgroud)

我只是想知道 的设计选择std::array,以及为什么这样设计。

这不是一个由于错误而产生的问题,而是一个为什么std::array<>要以这种方式设计的问题。

Hen*_*her 12

std::array<T,N> var旨在作为 C 风格数组的更好替代品T var[N]。

该对象的内存空间是本地创建的,即在局部变量的堆栈上或在定义为成员时在结构本身内部创建。

std::vector<T>相反,总是在堆中分配其元素的内存。

因此,std::array在本地分配时,它不能具有可变大小,因为需要在编译时保留该空间。std::vector另一方面,由于其内存是无限的,因此能够重新分配和调整大小。

因此,std::array在性能方面的一大优势是它消除了std::vector为其灵活性付出代价的一层间接性。

例如:

#include <cstdint>
#include <iostream>
#include <vector>
#include <array>

int main() {
    int a;
    char b[10];
    std::vector<char> c(10);
    std::array<char,10> d;
    struct E {
        std::array<char,10> e1;
        std::vector<char> e2{10};
    };
    E e;

    printf( "Stack address:   %p\n", __builtin_frame_address(0));
    printf( "Address of a:    %p\n", &a );
    printf( "Address of b:    %p\n", b );
    printf( "Address of b[0]: %p\n", &b[0] );
    printf( "Address of c:    %p\n", &c );
    printf( "Address of c[0]: %p\n", &c[0] );
    printf( "Address of d:    %p\n", &d );
    printf( "Address of d[0]: %p\n", &d[0] );
    printf( "Address of e:    %p\n", &e );
    printf( "Address of e1:   %p\n", &e.e1 );
    printf( "Address of e1[0]:%p\n", &e.e1[0] );
    printf( "Address of e2:   %p\n", &e.e2);
    printf( "Address of e2[0]:%p\n", &e.e2[0] );
}
Run Code Online (Sandbox Code Playgroud)

生产

Program stdout
Stack address:   0x7fffeb115ed0
Address of a:    0x7fffeb115eb0
Address of b:    0x7fffeb115ea6
Address of b[0]: 0x7fffeb115ea6
Address of c:    0x7fffeb115e80
Address of c[0]: 0x1cad2b0
Address of d:    0x7fffeb115e76
Address of d[0]: 0x7fffeb115e76
Address of e:    0x7fffeb115e40
Address of e1:   0x7fffeb115e40
Address of e1[0]:0x7fffeb115e40
Address of e2:   0x7fffeb115e50
Address of e2[0]:0x1cad2d0
Run Code Online (Sandbox Code Playgroud)

上帝螺栓: https: //godbolt.org/z/75s47T56f