[英]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.