Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[18.218.184.214] |
|
Страницы: (3) [1] 2 3 все ( Перейти к последнему сообщению ) |
Сообщ.
#1
,
|
|
|
Здравствуйте!
Внезапно столкнулся с проблемкой. Объявил класс со статическими константами: class foo { public: static const int alpha; static const int beta; }; const int foo::alpha = _XXX_SIMBOL_ALPHA; const int foo::beta = _XXX_SIMBOLBETA; Ну и тут чудеса. В функции main (из main.obj) switch( val ) { case foo::alpha: case foo::beta: break; default: break; } Компилятор ms vs 2015 сказал, что foo::alpha не является константой! Но когда я перенёс этот switch в конструктор foo (в foo.obj), то всё чудесно отработало. Что тут можно сделать? Что тут можно поправить? Как сказать switch, что у меня действительно константы? В инете наткнулся на описание схожих ситуаций. Вроде бы банальность. А решения нет. Проскакивала мысль на счёт constexpr. Но компилятор хочет, чтоб я ему сразу предоставил значение. Чего-то там как-то не так. |
Сообщ.
#2
,
|
|
|
Несколько странный вопрос. Ибо: компилирует, скажем, компилятор такой левый файл с таким левым switch'ем, а вы опосля взяли и переправили значение. В итоге - несогласованность.
|
Сообщ.
#3
,
|
|
|
Цитата Eric-S @ Что тут можно сделать? Использовать enum или попробовать инициализировать поля прямо в объявлении класса static const int beta = _XXX_SIMBOLBETA; |
Сообщ.
#4
,
|
|
|
Цитата Славян @ Несколько странный вопрос. Ибо: компилирует, скажем, компилятор такой левый файл с таким левым switch'ем, а вы опосля взяли и переправили значение. В итоге - несогласованность. Замечание правомочно. Но ведь я и enum class могу изменить, с тем же успехом. Понятно, что такая ситуация возможно. Я о ней знаю. Но неужели ничего нельзя поделать? |
Сообщ.
#5
,
|
|
|
Если ты хочешь инить в другой единице трансляции, то компилятор правильно ругается и действительно ничего с этим не сделать, т. к. это не константа а константная переменная, что не одно и то же.
Добавлено Цитата Eric-S @ Но ведь я и enum class могу изменить, с тем же успехом. Не можешь. |
Сообщ.
#6
,
|
|
|
Цитата shm @ Использовать enum или попробовать инициализировать поля прямо в объявлении класса static const int beta = _XXX_SIMBOLBETA; Ох. Хорошо бы. Но эти константы, тянутся из одной страшненькой библиотеки. И я хотел бы скрыть эту пакость. Но сейчас подумываю на счёт промежуточного enum. В том смысле, что значение перечисления будет автоматом. А при необходимости, получить константу, внутри будет switch, который конвертнёт константу enum в константу int. int to_int( foo_enum val ) { switch( val ) { case foo_enum::alpha: return _XXX_SIMBOL_ALPHA; case foo_enum::beta: return _XXX_SIMBOL_BETA; } } Добавлено Цитата shm @ компилятор правильно ругается и действительно ничего с этим не сделать, т. к. это не константа а константная переменная, что не одно и то же. Ругается правильно. Справедливо, правомочно и логично. Но неужели нет ни одного внятного трюка для укращения? |
Сообщ.
#7
,
|
|
|
Цитата Eric-S @ Ох. Хорошо бы. Но эти константы, тянутся из одной страшненькой библиотеки. И я хотел бы скрыть эту пакость Ну а зачем ты выносишь тогда эти константы наружу? Сделай обертки для функций из этой библиотеки и все. Добавлено А вообще, это ж макросы. Просто скопируй их оттуда к себе и не парься. |
Сообщ.
#8
,
|
|
|
Цитата Eric-S @ Объявил класс со статическими константами: Скрытый текст class foo { public: static const int alpha; static const int beta; }; const int foo::alpha = _XXX_SIMBOL_ALPHA; const int foo::beta = _XXX_SIMBOLBETA; Ну и тут чудеса. В функции main (из main.obj) switch( val ) { case foo::alpha: case foo::beta: break; default: break; } Компилятор ms vs 2015 сказал, что foo::alpha не является константой! а у меня все компилирует пробовал vs2008 щас протестил в vs2010-vs2015 все компилирует или я не правильно понял? Эриксон проправь меня, а то я с ума сойду |
Сообщ.
#9
,
|
|
|
Цитата Cfon @ Эриксон проправь меня, а то я с ума сойду Ты разделил единицы трансляции? Должно быть два объектных файла: foo.obj и main.obj. Добавлено Цитата Олег М @ Ну а зачем ты выносишь тогда эти константы наружу? Сделай обертки для функций из этой библиотеки и все. Как раз пишу статическую lib, в качестве обёртки. Но в частности, эти константы нужны пользователю, для обработки callback функции. Пользователь пишет функцию. Регистрирует её в моей обёртке. Затем библиотека дёргает эту функцию. А пользователь должен обработат сообщение через switch. Можно конечно if. Всё же функция простенькая, не какой-то там WinProc. Добавлено Цитата Олег М @ А вообще, это ж макросы. Просто скопируй их оттуда к себе и не парься. Угу. Ну да... А хорошо ли так делать? Подход гарантировано работающий сечас. Но в будущем ломабельный. И просто неэтичный. Добавлено Цитата shm @ Цитата Eric-S @ Но ведь я и enum class могу изменить, с тем же успехом. Не можешь. Не... Я в том смысле, что если я изменю enum в одном файле, то придётся перекомпилировать все файлы, где используется этот enum. |
Сообщ.
#10
,
|
|
|
Цитата Eric-S @ Я в том смысле, что если я изменю enum в одном файле, то придётся перекомпилировать все файлы, где используется этот enum. Иии? |
Сообщ.
#11
,
|
|
|
Цитата Славян @ Несколько странный вопрос. Ибо: компилирует, скажем, компилятор такой левый файл с таким левым switch'ем, а вы опосля взяли и переправили значение. В итоге - несогласованность. Цитата Eric-S @ Замечание правомочно. Но ведь я и enum class могу изменить, с тем же успехом. Понятно, что такая ситуация возможно. Я о ней знаю. Но неужели ничего нельзя поделать? Значит всё равно придётся перекомпилировать! Единственная сложность в дополнительной проверки изменений. Добавлено Цитата shm @ Иии? Да, нет. Ничо. Это я так, причетаю. Понятно же, что с enum, компилятору легче перепроверить кто когда изменился, поскольку enum открыт всем ветрам, опубликованный в хидере. |
Сообщ.
#12
,
|
|
|
Цитата Eric-S @ Угу. Ну да... А хорошо ли так делать? Подход гарантировано работающий сечас. Но в будущем ломабельный. И просто неэтичный В общем случае – нехорошо. А в частном – оцениваешь, стоит ли эта библиотека прилагаемых усилий, да еще в runtime. Чаще бывает, что проще скопировать значения. |
Сообщ.
#13
,
|
|
|
Цитата Олег М @ В общем случае – нехорошо. Потом будет лениво переделывать. Да и пользоватся странным интерфейсом стрёмно. Так что, если делать, то максимально хорошо. А в противном случае, проще юзать библиотеку, без всяких обёрток. |
Сообщ.
#14
,
|
|
|
Цитата Eric-S @ Потом будет лениво переделывать. Да и пользоватся странным интерфейсом стрёмно. Так что, если делать, то максимально хорошо. Проблема в том, что ты пытаешься перенести в runtime решение задачи - сравнение и сопоставление констант - которая может и должна решаться в compile-time. В данном случае, если тебе очень не хочется выносить наружу заголовок твоей библиотеки, можно просто сделать свой enum или свои константы совпадающие по значению с библиотечными. И проверять где-нибудь их соответствие при помощи static_assert. |
Сообщ.
#15
,
|
|
|
Вообщем я сделал свой enum class, с альтернативными кодами.
И две функции конвертирующие туда и обратно, через тот же самый switch. Заодно, в секции default, воткнул throw invalid_argument. Отработало всё нормально. Жаль, что моя версия компилятора не может это сделать constexpr, а в остальном результат устраивает. Но если у кого появятся альтернативные решения, прошу отписаться! Добавлено Цитата Олег М @ можно просто сделать свой enum или свои константы совпадающие по значению с библиотечными. И проверять где-нибудь их соответствие при помощи static_assert. Да! Это тоже хорошее, правильное решение. Проверять через static_assert. А приводить через reinterpret_cast? Добавлено Сейчас коммит оформлю, чтоб сохранить изменения с вариантом runtime. И попробую переделать с вариантом compile-time. |