简体   繁体   English

数组的C ++指针:为什么不能在函数begin(array)中使用间接计算的const var定义的数组?

[英]C++ pointer of array: why cannot use an array defined by indirectly computed const var in function begin(array)?

Error message in text: 文本中的错误消息:

I'm studying the book C++ Primer and encountering a problem listed below when coding an answer for one exercise: 我正在学习C ++ Primer一书,并在为一个练习编写答案时遇到下面列出的问题:

#include<iostream>
#include<vector>

using namespace std;

int main() {
int i  = 3;
const int ci = 3;
size_t si = 3;
const size_t csi = 3;
int ia[i];
int cia[ci];
int sia[si];
int csia[csi];
int another_a[] = {1,2,3};

int *pi = begin(ia);       // error here
// no instance of overloaded function "begin" matches the argument list -- 
// argument types are: (int [i])
int *pci = begin(cia);
int *psi = begin(sia);     // error here
// no instance of overloaded function "begin" matches the argument list -- 
// argument types are: (int [si])
int *pcsi = begin(csia);
int *p_ano = begin(another_a);

vector<int> v = {1,3,4};
const int m = v.size();
const size_t n = v.size();
int ma[m];
int na[n];
int *pm = begin(ma);    // error here
// no instance of overloaded function "begin" matches the argument list -- 
// argument types are: (int [m])
int *pn = begin(na);    // error here
// no instance of overloaded function "begin" matches the argument list -- 
// argument types are: (int [n])

system("pause");
return 0;
}

I can understand that the first two errors are because that those two arrays are not defined using an constant variable. 我可以理解前两个错误是因为这两个数组没有使用常量变量定义。 But why the last two, even if I have converted the size of the vector into a constant variable, the compiler still reports an error? 但是为什么最后两个,即使我已经将向量的大小转换为常量变量,编译器仍会报告错误?

在此输入图像描述

I'm quite confused about this, I would appreciate a lot for your kindly answer or discussion no matter it works or not. 我对此很困惑,无论是否有效,我都会非常感谢您的回答或讨论。

First and foremost, you are using a compiler extension, but more on that later. 首先,您正在使用编译器扩展,但稍后会有更多内容。

The standard begin overload which works for you is a template that accepts a reference to an array with a size that is a constant expression. 适用于您的标准begin重载是一个模板,它接受对大小为常量表达式的数组的引用。 In a nutshell, constant expressions are those expressions that a compiler can evaluate and know the value of during compilation. 简而言之,常量表达式是编译器可以评估并知道编译期间的值的那些表达式。

A constant integer initialized with a constant expression like const int ci = 3; 用常量表达式初始化的常量整数,如const int ci = 3; , can be used wherever a constant expression is required. ,可以在需要常量表达式的任何地方使用。 So ci is, for all intents an purposes, a constant expression itself (equal to 3). 因此,对于所有意图而言, ci本身就是一个常量表达式(等于3)。

Modern C++ has a way to make such varaibles stand out as intended constant expressions, it's the constexpr specifier. 现代C ++有一种方法可以使这些变量作为预期的常量表达式突出,它是constexpr说明符。 So you could define ci like this: 所以你可以像这样定义ci

constexpr int ci = 3;

It's exactly like your original code. 它与原始代码完全一样。 But the same will not work for const int m = v.size(); 但是对于const int m = v.size(); . Because constexpr requires a true constant expression as an initializer, unlike const . 因为constexpr需要一个真正的常量表达式作为初始化器,不像const For a const variable is not necessarily a constant expression. 对于const变量,不一定是常量表达式。 It can just be a run-time variable that you cannot modify. 它只能是您无法修改的运行时变量。 And this is the case with m . 这就是m的情况。

Because m is not a constant expression, what you defined is a variable length array . 因为m不是常量表达式,所以您定义的是可变长度数组 AC feature that is sometimes introduced as an extension by C++ compilers. AC功能有时作为C ++编译器的扩展引入。 And it doesn't gel with the std::begin template, which expects the array extent to be a constant expression . 并且它不会与std::begin模板凝聚,后者期望数组范围是一个常量表达式

Declaring arrays with non constant indexes isn't standard c++. 声明具有非常量索引的数组不是标准的c ++。

If you need dynamically sized arrays use std::vector . 如果需要动态大小的数组,请使用std::vector

Declaring a variable as const doesn't make it a compile time constant (required to declare a fixed sized array) it just means you can't modify it after it is declared. 将变量声明为const不会使它成为编译时常量(声明一个固定大小的数组所需),这只是意味着在声明它之后就无法修改它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM