如何根据向量的大小声明数组
How can I declare an array from the size of a 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()
不能是一个常量表达式(尽管我不确定是否是这样)。在这种情况下,我如何在不必手动输入元素数量的情况下做到这一点?
截至目前,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
s可用于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] << " ";
通常,不可能将向量复制到数组中,因为通常的数组是constexpr
,而向量大小不是,它是动态大小。也有一些编译器支持的动态数组,但话说回来,它们的大小从来都不是constexpr
。我想,你们只需要使用向量。
我不知道你的动机,但。。。
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;
}
您需要分配内存,因为正如您所说,向量大小不是常数:
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;
}
您似乎想要获取初始值设定项列表中产生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[]>
的使用确保分配的内存自动释放。
constexpr
是常量表达式,它是在编译时求值的表达式。它在编译时是已知的,这是constexpr
的一个基本特性。
考虑到这一点,您可以看到,在运行时尝试构建一个非动态分配的C样式数组是没有意义的,因为只有在运行时才知道元素的数量。这两个想法是正交的。
从技术角度来看,不能从非常量表达式初始化constexpr
。vector::size()
是非constexpr
,所以正如你所怀疑的,它不仅不可编译,而且从设计的角度来看,试图从它构建constexpr
也是不合乎逻辑的:
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());
}
我会避免
constexpr size_t size = ivec.size();
int arr[size];
像这个一样
size_t size = ivec.size();
int* arr = new int[size];
然后像处理不断分配的数组一样处理它。阅读有关动态分配阵列的更多信息。别忘了去
delete[] array;
在C++11中,数组可以声明为堆栈上的运行时绑定:(注:这只是根据最新的草案:http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3690.pdf并且可能不是标准的,但是g++与-std=c++11
将允许它
注意,is不是constexpression:
8.3.4阵列[dcl.array]
D1〔expressionopt〕属性说明符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;
}
你的编译器可能允许也可能不允许,所以这取决于你需要成为的严格标准
- 在类c++中使用new声明数组
- 为什么不能用常量表达式声明数组?
- 声明数组后我无法添加数组
- 可以使用<size_t>static_const(),std::as_const()或static_cast<const size_t>()来声明数组吗?
- 变量未在此范围内声明 数组线性搜索
- 在类中声明数组. C++
- T D[N] 总是声明数组类型的对象吗?
- 如何使用智能指针在二维上声明数组?
- 声明数组>> int arr[] 时出错;在C++(虽然在 Java 中有效)?
- 在C 类中声明数组数据
- 声明数组时出现 SIGSEGV 错误,而不创建新的 int[size]
- 如何在不初始化常量的情况下声明数组?
- 使用函数在函数中声明数组值
- 以C++声明数组的时间复杂度
- 通过传递数组长度在函数内声明数组
- 通过引用传递数组,而不在函数声明中显式声明数组的大小
- 声明数组和打印[错误?]
- 用内核参数在CUDA内核中声明数组
- 如何在不依赖#Define的情况下转发声明数组大小
- 声明数组已经填充了零