LINUX.ORG.RU

C++ Создание статического массива внутри класса

 , , ,


0

4

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

class MyClass
{
static const char arr[10] {'1','2', ... ,'9'};
}

выдает: ошибка: «constexpr» требуется для инициализации внутри класса статического элемента данных «char Card::arr [4]» нецелого типа [-fpermissive]

не пойму в чем проблема)))

флаги компилятора:
g++ -fexceptions -std=c++14 -g -Wextra -Wall -Werror 


решение: тут

★★

Последнее исправление: safocl (всего исправлений: 3)

в старом с++ так нельзя, нужно выносить константы из класса в .cpp, тут компилятор предлагает поменять const на constexpr

anonymous
()

Нужно использовать указатель и неплохо бы инициализировать 10-й элемент как конец строки.

static тож убрать скорее всего нужно.

grem ★★★★★
()
Последнее исправление: grem (всего исправлений: 1)
Ответ на: комментарий от grem

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

safocl ★★
() автор топика
Ответ на: комментарий от mos

был там, но однако не увидил решения.

safocl ★★
() автор топика
Ответ на: комментарий от anonymous

как понять в старом? вроде использую последний стабильный стандарт... или надо ставить 17-ый стандарт в котором так будет работать?

safocl ★★
() автор топика
Ответ на: комментарий от anonymous

и у меня все в одном файле пока что, только начало задумки, обучаюсь и попутно реализую весч

safocl ★★
() автор топика

если пытаюсь присвоить определенному в классе static указателю на объект типа char, то получается:
undefined reference to `MyClass::arr'

class MyClass
{
static const char *arr;
}

int main ()
{
const char arr[2]{'1','2'};
MyClass::arr = arr;
}

safocl ★★
() автор топика
Последнее исправление: safocl (всего исправлений: 1)
Ответ на: комментарий от anonymous

да, с -std=c++17 роббит шапочный вариант.

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

safocl ★★
() автор топика
Ответ на: комментарий от safocl

Начиная с C++11 можно использовать std::array. Но размер нужно знать на этапе компиляции.

Meyer ★★★★★
()
Ответ на: комментарий от safocl

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

Тебе уже компилятор сказал — constexpr

anonymous
()
Ответ на: комментарий от safocl

ЕМНИП во всех стандартах static поля должны инициализироваться за пределами класса, за исключением constexpr:

class MyClass
{
static const char arr[10];
};
const char MyClass::arr[10] = {'1','2', ... ,'9'};
Vinick ★★
()
Ответ на: комментарий от safocl

С чего вдруг он последний? К тому же, нету такого понятия как «стабильный» - ты придумал какую-то ахинею. Стабильным может быть имплементация в компиляторе, не более того.

nebanbmenyapls
()
Ответ на: комментарий от safocl

не подумал бы чо такую простую весч реализавали тока год назад.

С чего вдруг она простая? Ты мне покажешь хоть один недоязычок, в котором есть constexpr? static тоже достаточно фундаментальная вещь.

А так да, С++ валялся на помойке до середины 10х годов.

как для ранних стандартов такую задачу реализовать.

Выше показали, инициализация(вернее создание/определение поля, ведь там можно написать только объявление) возможна только внешняя, т.е. изнутри класса.

nebanbmenyapls
()

выдает: ошибка: «constexpr» требуется для инициализации

компилятор написал не просто где ошибка, но ещё и как её починить

next_time ★★★★★
()
Ответ на: комментарий от anonymous

в таком случае если ниже -std=c++17 стоит, то при обращении внутриклассовой функции (метода класса) к ентому массиву, пишет

undefined reference to `Card::ValueCardArr'

safocl ★★
() автор топика
Ответ на: комментарий от nebanbmenyapls

беги от старых стандартов пока не поздно.

так вроде и делаю. просто пока не дошел еще до изучения новых фитч, надо бы вспомнить основы, сча вот классы как раз начал сочинять под реализацию прог, наследование сча изучаю)) потом буду новые разработанные классы изучать потипу векторов и т.д.

safocl ★★
() автор топика
Ответ на: комментарий от CatsCantFly

проблема в том, чо я не знал такого кейворда, как constexpr...
вот и думал чо он мне за ахинею толкует, потому чо компилятор явно не указал чо именно надо заменить const на constexpr.

safocl ★★
() автор топика
Ответ на: комментарий от Vinick

в об щем, всем спс, ентот ответ является самым подходящим, т.к. роббит как я и планировал.

safocl ★★
() автор топика
Ответ на: комментарий от nebanbmenyapls

перед началом обновления обучения))) смотрел стандарты, реализованные в гцц, и там с++20 пока не весь реализован был, неделю назад где то. да и с++17 считается вроде эксперементальным.

safocl ★★
() автор топика
Ответ на: комментарий от nebanbmenyapls

ах, да, не указал чо у меня арч, там гцц:

`--> g++ --version
g++ (GCC) 8.2.1 20180831

safocl ★★
() автор топика
Ответ на: комментарий от safocl

роббит
чо
весч
реализавали
енто

Ты специально коверкаешь слова?

anonymous
()
Ответ на: комментарий от invy

до ентава типа данных, или как я подозреваю класса, я еще не дошел... мож и приму на вооружение, наслышан о классе вектор.

safocl ★★
() автор топика
Ответ на: комментарий от nebanbmenyapls

Ты мне покажешь хоть один недоязычок, в котором есть constexpr?

Ну как бы `constexpr` костыль по сути то. Его фукнкциональность может быть реализована без отдельного ключевого слова. Например так сделано в D. Там нет этого ключевого слова, однако в компайл тайме можно сделать много чего чего в плюсах никак не сделать. Даже с `constexpr`. Хотя если `if constexpr` брать то в D есть более мощная конструкция `static if`. Уже то, что она не вводит отдельный скоуп делает ее намного полезнее `if constexpr` - я вообще не понимаю, как умные люди могли пойти на такой шаг как создание scope. Также на D нет необходимости делать, скажем функцию, в `constexpr` варианте, компилятор сам выводит может эта функция быть использована в компайл тайме или нет. В общем я бы не хвалился наличием `constexpr` в плюсах, это скорее костыльная реализация очень полезной фичи. В этом плане это плюсы «недоязычок».

yetanother ★★
()
Ответ на: комментарий от yetanother

компилятор [D] сам выводит может эта функция быть использована в компайл тайме или нет

RTFM

anonymous
()
Ответ на: комментарий от yetanother

Ну как бы `constexpr` костыль по сути то.

constexpr это мусорная параша, как и С++. Но мы сейчас не об этом.

Его фукнкциональность может быть реализована без отдельного ключевого слова. Например так сделано в D.

Зачем ты инициируешь эту клоунду? «например в D», будто бы ты мне можешь привести ещё примеры.

Там нет этого ключевого слова, однако в компайл тайме можно сделать много чего чего в плюсах никак не сделать.

Например. Меня мало волнует какое-то ключевое слово, дело не в нём. Ты говоришь лучше - основная проблема constexpr в крестах это то, что он мусор. Это константа времени компиляции, а константы нахрен никому не упёрлись и являются целиком и полностью несостоятельными.

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

Уже то, что она не вводит отдельный скоуп делает ее намного полезнее `if constexpr`

Это полная херня. Ты сравниваешь две разные вещи. if constexpr в крестах это просто if, который обладает семантикой if, которая(очевидно) нужна.

Твой if это совершенно другая вещь. И очевидно, что он не отменяет первого и точно так же нужен.

Также на D нет необходимости делать, скажем функцию, в `constexpr` варианте, компилятор сам выводит может эта функция быть использована в компайл тайме или нет.

Это убогий костыль, который ничего не значит. Суть constexpr не в том, чтобы объявить функцию constexpr, а для того, чтобы определить constexpr контекст.

Конечно, ты сам можешь определять constexpr-контекст, но опять же - это будет неявно. А значит, что я не могу гарантированно получить constexpr. Это проблема.

В общем я бы не хвалился наличием `constexpr` в плюсах, это скорее костыльная реализация очень полезной фичи.

Проблема в том, что этой фичи нигде нет. Ты можешь назвать лишь d, который родил крестовый адепт. Очевидно, что там должны быть фичи крестов.

В этом плане это плюсы «недоязычок».

Не существует такого «в плане» - всем насрать на какие-то планы. Меня интересует язык как множество этих планов.

В этой плане у Васи чуть кривая рука, а вот у Пети чуть ровнее. Только вот нюансы - у Пети нет ног и рука одна. А так да - в этом плане он лучше Васи, только это мало что меняет.

nebanbmenyapls
()
Ответ на: комментарий от nebanbmenyapls

Зачем ты инициируешь эту клоунду? «например в D», будто бы ты мне можешь привести ещё примеры.

Да я без задней мысли использовал этот оборот.

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

Есть, называется compile time function execution - CTFE. При этом не нужно писать разные варианты для runtime и compiletime - код один и тот же. Правда не все возможности языка доступны в CTFE, но тем не менее многое. Существует драйвер для sqlite который на чтение полностью работает в компайл тайме. Деталей не расскажу особенно, так как просто пользуюсь языком и могу поплыть в этих деталях, но как я понял, машинный код, который генерируется для этого драйвера не вызывает функции sqlite для доступа к данным, а напрямую обращается к записям базы на низком уровне. Т.е. sql запрос сразу преобразуется в доступ к полям.

Еще сейчас пилится новая версия движка CTFE, которая позволяет использовать больше возможностей языка, не жрет память как текущая реализация и быстрее.

Насколько я понял - это не деструкторы из С++, а просто дристня, которую вызывает gc. Если это так - закапывайте. Нахрен нужен язык без деструкторов? Как на нём вообще писать?

Дело в том, что в Д есть четкое разделение между классами и структурами. Классы это референсные типы, по умолчанию размещаемые в куче, время жизни у них это время жизни всего приложения, деструкторы вызываются при сборке мусора и могут вообще не быть вызваны. Структуры это типы-значения, по умолчанию размещаются на стеке, время жизни определяется областью видимости и у них деструкторы работают как в плюсах. Конечно, при желании можно структуры разместить на куче используя new или аллокатор, а класс на стеке используя scoped - вот тут уже деструктор класса будет вызван при выходе из области видимости.

yetanother ★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.