1369 / 592 / 199
Регистрация: 02.08.2011
Сообщений: 2,882
|
||||||
1 | ||||||
Двумерный массив <array>. const int value = array.size(); value не константа?14.05.2016, 16:15. Показов 5533. Ответов 36
Метки нет Все метки)
(
0
|
|
14.05.2016, 16:15 | |
Ответы с готовыми решениями:
36
Расстановка девяти чисел (Turbo C) Выводит ошибку using Matrix = std::array<std::array<int, 3>, 3>; и bool NextSet Присвоить значения переменных в массив Array (class Array в Turbo C++) SIZE of array is not computable |
1369 / 592 / 199
Регистрация: 02.08.2011
Сообщений: 2,882
|
|
14.05.2016, 17:19 [ТС] | 3 |
Я предпочту увидеть ответ на заданный вопрос. Пример не компилируется, почему?
Добавлено через 30 минут Всё. Вспомнил. Ответ не нужен.
0
|
Вездепух
![]() ![]() 10818 / 5840 / 1584
Регистрация: 18.10.2014
Сообщений: 14,493
|
|
14.05.2016, 19:33 | 4 |
Пример не компилируется потому, что в языке С++ целочисленное
const значение является Целочисленным Константным Выражением тогда и только тогда, когда его инициализатор является Целочисленным Константным Выражением.В вашем случае ROW инициализировано при помощи вызова constexpr метода std::array<>::size() через ссылку. Методы, вызванные через ссылку, не порождают Целочисленного Константного Выражения, даже если эти методы являются constexpr .
1
|
1369 / 592 / 199
Регистрация: 02.08.2011
Сообщений: 2,882
|
|
14.05.2016, 19:52 [ТС] | 5 |
В моём случае: то, что я в ROW пихаю, неизвестно на этапе компиляции;
Вот и всё.
0
|
Вездепух
![]() ![]() 10818 / 5840 / 1584
Регистрация: 18.10.2014
Сообщений: 14,493
|
|
14.05.2016, 20:19 | 6 |
Ну это было бы слишком просто. Это вы фактически перефразировали сообщение об ошибке.
Сразу надо заметить, что ваш оригинальный код прекрасно компилируется gcc http://coliru.stacked-crooked.... 4ad15dc04f А вот clang выдает ошибку http://coliru.stacked-crooked.... 3a33d6f578 То есть вопрос несколько неоднозначный. Метод std::array<>::size() является constexpr , причем его результат напрямую определяется шаблонным параметром. Т.е. теоретически это значение прекрасно известно на этапе компиляции и теоретически у компилятора есть все необходимое для того, чтобы вычислить это constexpr именно как constexpr , т.е. именно на этапе компиляции. Что gcc и делает.Для clang, похоже, преградой тут является именно вызов constexpr метода через ссылку. Если в вашем примере убрать ссылку с объявления параметра, то пример начнет прекрасно компилироваться и в clang. А вот как правильно - надо разбираться...
2
|
1369 / 592 / 199
Регистрация: 02.08.2011
Сообщений: 2,882
|
|
14.05.2016, 21:11 [ТС] | 7 |
Ну, не эксперт я, я - чайник.
Некоторые компиляторы при оптимизациях иногда умеют вычислять то, что предполагается константой ещё до выполнения. То есть фактически это так и выглядит, что вроде должно быть неизвестно, но как по мановению волшебной палочки почему-то известным становится ещё до компиляции. Как-то так. В общем, правильно как в clang, а оптимизации эти - это оптимизации. Добавлено через 3 минуты Если надо разбираться, я как бы не против. Добавлено через 41 минуту Студия так пишет:
0
|
Вездепух
![]() ![]() 10818 / 5840 / 1584
Регистрация: 18.10.2014
Сообщений: 14,493
|
|
14.05.2016, 21:13 | 8 |
Такая логика применима именно и только к оптимизациям - то есть к контекстам, в которых формально безразлично, будет ли значение вычислено на этапе компиляции или на этапе выполнения. Это чисто количественный вопрос, ибо такие контексты не влияют на корректность (то есть компилируемость) программы.
Когда же речь заходит о таких принципиальных качественных вопросах, как формирование Целочисленных Константных Выражений, т.е. решениях, влияющих на компилируемость кода, то тут спецификация языка никакой свободы компиляторам не предоставляет. Контексты, в которых const и constexpr обязаны порождать Целочисленные Константные Выражения (т.е. порождать значения, известные на стадии компиляции), оговорены однозначно.Вопрос в данном случае только в том, относится ли данный случай к набору таких контекстов.
2
|
![]() ![]() |
|
14.05.2016, 21:31 | 9 |
Сдаётся мне, если есть два массива
C++ array<int,10> a; array<int,20> b; shuffle_row(a); shuffle_row(b);
1
|
1369 / 592 / 199
Регистрация: 02.08.2011
Сообщений: 2,882
|
|
14.05.2016, 21:47 [ТС] | 10 |
Ну gcc считает возможной, я на сайте том же проверил, на который тут сослано.
Хотя по логике возможным быть не должно. Добавлено через 4 минуты Коли о ссылках рассуждать, то я бы и о && не хотел забывать. Там тоже как с &.
0
|
Вездепух
![]() ![]() 10818 / 5840 / 1584
Регистрация: 18.10.2014
Сообщений: 14,493
|
|
14.05.2016, 22:06 | 11 |
В смысле? С точки зрения классической инстанциации
shuffle_row<T> , array<int,10> и array<int,20> - это два совершенно разных, совершенно независисмых типа Т . Поэтому в данном примере будет инстанциироваться две отдельных, ничего друг о друге не знающих специализации функции shuffle_row : скажем shuffle_row_std_array_int_10 и shuffle_row_std_array_int_20 . В каждой будет свой массив temp и никаких неоднозначностей с его размером не будет.В этом коде нет shuffle_row<int> . В этом коде инстанциируется именно shuffle_row<std::array<...>> , а это совсем другая история.Это зачем это его запрещать? Это фундаметальная функциональность шаблонов. А уж то, что автор кода применил ее именно так - это вопрос к автору кода.
1
|
1369 / 592 / 199
Регистрация: 02.08.2011
Сообщений: 2,882
|
||||||
14.05.2016, 23:03 [ТС] | 13 | |||||
Итак, обсуждаем теперь
0
|
2549 / 1208 / 358
Регистрация: 30.11.2013
Сообщений: 3,826
|
|
18.05.2016, 01:37 | 14 |
daslex, я не спец как вот hoggy может вам ответить , но вроде бы ответ очевиден - ссылка это абстрактная сущность времени выполнении: для взятия размера нужен объект (дяда с адрессом, который оживает только вовремя выполнения)
0
|
1369 / 592 / 199
Регистрация: 02.08.2011
Сообщений: 2,882
|
|
18.05.2016, 01:43 [ТС] | 15 |
А без ссылки не абстрактная сущность времени выполнения?
0
|
![]() 8720 / 4300 / 958
Регистрация: 15.11.2014
Сообщений: 9,744
|
|
18.05.2016, 02:09 | 16 |
ссылки - псевдонимы имен объектов. а компиляторы замечательно умеют различать объекты по их именам. 2. ссылки могут быть использованы в качестве параметров шаблона. 3. к конкретно данной ситуации (#13) ссылки не имеют ни малейшего отношения. код валидный, и успешно собирается компиляторами, которые поддерживают constexpr. проблема с компиляторами студии: они до сих пор его не осилили.
0
|
Вездепух
![]() ![]() 10818 / 5840 / 1584
Регистрация: 18.10.2014
Сообщений: 14,493
|
|
18.05.2016, 02:18 | 17 |
Как уже говорилось выше, код НЕ собирается clang - ошибка в обоих функциях одна и та же
Код
clang -std=c++14 -pedantic-errors main.cpp main.cpp:10:25: error: constexpr variable 'ROW' must be initialized by a constant expression constexpr int ROW = arr.size(); ^~~~~~~~~~ main.cpp:15:25: error: constexpr variable 'ROW' must be initialized by a constant expression constexpr int ROW = arr.size(); ^~~~~~~~~~ constexpr , однако не считает arr.size() константным выражением, пока вызов делается через ссылку.
0
|
![]() 8720 / 4300 / 958
Регистрация: 15.11.2014
Сообщений: 9,744
|
|
18.05.2016, 02:45 | 18 |
значит он так же не осилил constexpr
Добавлено через 3 минуты я понял.
0
|
Вездепух
![]() ![]() 10818 / 5840 / 1584
Регистрация: 18.10.2014
Сообщений: 14,493
|
|
18.05.2016, 03:15 | 19 |
Нет, как раз таки в данном случае похоже, что это именно GCC позволяет себе слишком много и/или пытается бежать впереди паровоза.
Добавлено через 12 минут А именно, согласно цитате, которую мне подсказали на StackOverflow, core constant expression e не должно содержать вычисления
1
|
1369 / 592 / 199
Регистрация: 02.08.2011
Сообщений: 2,882
|
||||||||||||||||
24.05.2016, 21:16 [ТС] | 20 | |||||||||||||||
Я тут немного подумал, так как словечки выше какие-то заморские, непонятные, и вот что решил:
======================== Я может где немного неправильно выразился, но суть должна быть понятна. Если так рассуждать, то как-то легко всё встаёт на свои места и напрашивается вывод на глюк в тексте предупреждения.
0
|
24.05.2016, 21:16 | |
Помогаю со студенческими работами здесь
20
Переписать программу через класс Array (двумерный массив).
Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |