C ++ указатель массива: почему нельзя использовать массив, определенный косвенно вычисленной const var в функции begin (array)? - PullRequest
0 голосов
/ 04 марта 2019

Сообщение об ошибке в тексте:

Я изучаю книгу 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;
}

Я могу понять, что первые две ошибки связаны с тем, что эти два массива не определены с использованием постоянной переменной. Но почему последние два, даже если я преобразовал размер вектора в постоянную переменную, компилятор все равно сообщает об ошибке?

enter image description here

IЯ очень смущен этим, я был бы очень признателен за ваш любезный ответ или обсуждение, независимо от того, работает он или нет.

Ответы [ 2 ]

0 голосов
/ 04 марта 2019

Прежде всего, вы используете расширение компилятора, но об этом позже.

Стандартная перегрузка begin, которая работает для вас - это шаблон, который принимает ссылку намассив с размером, который является константным выражением.В двух словах, константные выражения - это те выражения, которые компилятор может оценить и узнать значение во время компиляции.

Постоянное целое число, инициализированное постоянным выражением, таким как const int ci = 3;, может использоваться везде, где требуется постоянное выражение,Таким образом, ci для всех целей является самим константным выражением (равным 3).

В современном C ++ есть способ выделить такие переменные в виде намеченных константных выражений, это спецификатор constexpr,Таким образом, вы можете определить ci так:

constexpr int ci = 3;

Это точно так же, как ваш исходный код.Но то же самое не будет работать для const int m = v.size();.Потому что constexpr требует истинного константного выражения в качестве инициализатора, в отличие от const.Для const переменная не обязательно является константным выражением.Это может быть переменная времени выполнения, которую вы не можете изменить.И это в случае с m.

Поскольку m не является константным выражением, вы определили массив переменной длины .Функция AC, которая иногда вводится как расширение компиляторами C ++.И это не гель с шаблоном std::begin, который ожидает, что экстент массива будет константным выражением .

0 голосов
/ 04 марта 2019

Объявление массивов с непостоянными индексами не является стандартным c ++.

Если вам нужны массивы динамического размера, используйте std::vector.

Объявление переменной как const не делает ееконстанта времени компиляции (требуется для объявления массива фиксированного размера), это просто означает, что вы не можете изменить его после того, как он объявлен.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...