如何从向量的大小声明一个数组?

时间:2013-12-23 20:09:08

标签: c++ arrays vector

我正在尝试将矢量复制到数组中但是我不知道如何从矢量的大小声明数组。

代码:

int main() {
    vector<int> ivec = {1, 2, 3, 4, 5};
    constexpr size_t size = ivec.size();
    int arr[size];
    for(size_t i = 0; i < ivec.size(); ++i)
        arr[i] = ivec[i];
    for(size_t i : arr)
        cout << i << endl;
    return 0;
}

但是,我认为这不会编译,因为ivec.size()不能是一个常量表达式(虽然我不确定是否是这种情况)。在这种情况下,如何在不必手动输入元素数量的情况下执行此操作?

8 个答案:

答案 0 :(得分:3)

截至目前std::vector size()不是constexpr,因此您无法在constexpr次会议中使用它。因此,您可以尝试将new关键字用于动态大小的数组,但这样做毫无意义,因为您已经在使用向量。

vector<int> vi = {1, 2, 3, 4, 5};
int* arr = new int[vi.size()];
std::copy(vi.begin(), vi.end(), arr);
for (unsigned int i = 0; i < vi.size(); i++)
    std::cout << arr[i] << " ";
delete[] arr;

注意::您可以将std::begin()与第二个示例一起使用,因为arr[]是一个数组但不是第一个示例,因为arr*是一个指针。但是,std::copy()同时接受这两个,所以应该没问题。

initializer_list可以在constexpr次会议中使用:

constexpr initializer_list<int> il = {1, 2, 3, 4, 5};
int arr[il.size()];
std::copy(il.begin(), il.end(), std::begin(arr));
for (unsigned int i = 0; i < il.size(); i++)
    std::cout << arr[i] << " ";

答案 1 :(得分:0)

通常,无法将矢量复制到数组中,因为通常的数组是constexpr,而矢量大小不是,它是动态大小。某些编译器也支持动态数组,但同样,大小永远不会constexpr。 我想,你只需要使用矢量。

答案 2 :(得分:0)

我不知道你的动机,但......

int main() {
    vector<int> ivec = {1, 2, 3, 4, 5};
    constexpr size_t size = ivec.size();
    int* arr = (int*)malloc( sizeof( int * size ) );
    for(size_t i = 0; i < ivec.size(); ++i)
        arr[i] = ivec[i];
    for(size_t i : arr)
        cout << i << endl;
    free( arr );
    return 0;
}

答案 3 :(得分:0)

我要避免

constexpr size_t size = ivec.size();
int arr[size];

并按照这样做

size_t size = ivec.size();
int* arr = new int[size];

然后你像经常分配的数组一样处理它。阅读更多关于动态分配的数组 并且不要忘记

delete[] array;

答案 4 :(得分:0)

你需要分配内存,因为你所说的矢量大小不是常数:

int main() {
    vector<int> ivec = { 1, 2, 3, 4, 5 };
    size_t size = ivec.size();
    int *arr = new int[size]; // allocate memory
    for (size_t i = 0; i < ivec.size(); ++i)
        arr[i] = ivec[i];
    for (size_t i = 0; i < size; ++i)
        cout << i << endl;
    delete [] arr;  // release memory
    return 0;
}

答案 5 :(得分:0)

似乎你想要掌握初始化列表中产生constexpr的元素数量。我知道这样做的唯一方法是使用

#include <cstddef>
template <typename T, std::size_t N>
constexpr std::size_t size(T(&)[N]) {
    return N;
}

int main() {
    int vec[] = { 1, 2, 3, 4, 5 };
    constexpr std::size_t s = size(vec);

    int array[s];
    std::copy(std::begin(vec), std::end(vec), array);
}

如果你真的需要使用std::vector<T>作为来源,你需要分配内存,可能首先使用std::vector<T>!如果您想自己分配内存,可以使用以下内容:

std::vector<int> vec = { 1, 2, 3, 4, 5 };
std::unique_ptr<int[]> array(new int[vec.size()]);
std::copy(vec.begin(), vec.end(), array.get());

使用std::unique_ptr<int[]>可确保自动释放已分配的内存。

答案 6 :(得分:0)

constexpr常量表达式,它是在编译时计算的表达式。在编译时知道它是constexpr的基本特征。

鉴于此,您可以看到在运行时尝试构造非动态分配的C样式数组是没有意义的,因为元素的数量只能在运行时获知。这两个想法是正交的。

从技术角度来看,您无法从非常量表达式初始化constexprvector::size()不是constexpr,因此您怀疑它不仅不可编译,而且从设计的角度来看,尝试从中构建constexpr也是不合逻辑的:< / p>

constexpr size_t size = ivec.size(); // NO GOOD!

所有这些都说,从vector构建C风格的数组是非常非常。您首先使用vector进行了正确的事。现在不要把它复制到一个糟糕的阵列上来搞乱它。

vector保证有充足的存储空间。这意味着你可以像大多数情况下的C风格数组一样使用它。您需要做的就是将地址(或引用)传递给vector中的第一个元素,以及任何期望C样式数组的元素,它将正常工作。

void AincentApiFunction (int* array, size_t sizeofArray);

int main()
{
  std::vector <int> v;
  // ...

  AincentApiFunction (&v[0], v.size());
}

答案 7 :(得分:0)

在C ++ 11中,数组可能被声明为堆栈上的运行时绑定: (注意:这仅适用于最新的草稿:http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3690.pdf并且可能不是标准的,但带有-std=c++11的g ++将允许它

请注意,这不是表达:

8.3.4数组[dcl.array]

D1 [expressionopt] attribute-specifier-seqopt

标准示例:

void f(unsigned int n) {
    int a[n]; // type of a is “array of runtime bound of int”
}

所以你需要做的就是删除 constexpr:

int main() {
    vector<int> ivec = {1, 2, 3, 4, 5};
    size_t size = ivec.size();                  // this is fine
    int arr[size];
    for(size_t i = 0; i < ivec.size(); ++i)
        arr[i] = ivec[i];
    for(size_t i : arr)
        cout << i << endl;
    return 0;
}

您的编译器可能允许也可能不允许这样做,因此取决于您需要的严格标准