На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
Модераторы: Qraizer, Hsilgos
Страницы: (3) [1] 2 3  все  ( Перейти к последнему сообщению )  
> case ругается на поле static const
    Здравствуйте!

    Внезапно столкнулся с проблемкой.

    Объявил класс со статическими константами:
    ExpandedWrap disabled
      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)

    ExpandedWrap disabled
      switch( val )
      {
      case foo::alpha:
      case foo::beta:
      break;
      default:
      break;
      }


    Компилятор ms vs 2015 сказал, что foo::alpha не является константой!

    Но когда я перенёс этот switch в конструктор foo (в foo.obj), то всё чудесно отработало.

    Что тут можно сделать? Что тут можно поправить? Как сказать switch, что у меня действительно константы?

    В инете наткнулся на описание схожих ситуаций. Вроде бы банальность. А решения нет.

    Проскакивала мысль на счёт constexpr. Но компилятор хочет, чтоб я ему сразу предоставил значение. Чего-то там как-то не так.
      Несколько странный вопрос. Ибо: компилирует, скажем, компилятор такой левый файл с таким левым switch'ем, а вы опосля взяли и переправили значение. В итоге - несогласованность. :oops:
        Цитата Eric-S @
        Что тут можно сделать?

        Использовать enum или попробовать инициализировать поля прямо в объявлении класса
        ExpandedWrap disabled
          static const int beta = _XXX_SIMBOLBETA;
        Сообщение отредактировано: shm -
          Цитата Славян @
          Несколько странный вопрос. Ибо: компилирует, скажем, компилятор такой левый файл с таким левым switch'ем, а вы опосля взяли и переправили значение. В итоге - несогласованность. :oops:

          Замечание правомочно.
          Но ведь я и enum class могу изменить, с тем же успехом.

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

            Добавлено
            Цитата Eric-S @
            Но ведь я и enum class могу изменить, с тем же успехом.

            Не можешь.
            Сообщение отредактировано: shm -
              Цитата shm @
              Использовать enum или попробовать инициализировать поля прямо в объявлении класса
              ExpandedWrap disabled
                static const int beta = _XXX_SIMBOLBETA;

              Ох. Хорошо бы. Но эти константы, тянутся из одной страшненькой библиотеки. И я хотел бы скрыть эту пакость.

              Но сейчас подумываю на счёт промежуточного enum.
              В том смысле, что значение перечисления будет автоматом.
              А при необходимости, получить константу, внутри будет switch, который конвертнёт константу enum в константу int.
              ExpandedWrap disabled
                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 @
              компилятор правильно ругается и действительно ничего с этим не сделать, т. к. это не константа а константная переменная, что не одно и то же.

              Ругается правильно. Справедливо, правомочно и логично.
              Но неужели нет ни одного внятного трюка для укращения?
                Цитата Eric-S @
                Ох. Хорошо бы. Но эти константы, тянутся из одной страшненькой библиотеки. И я хотел бы скрыть эту пакость

                Ну а зачем ты выносишь тогда эти константы наружу? Сделай обертки для функций из этой библиотеки и все.

                Добавлено
                А вообще, это ж макросы. Просто скопируй их оттуда к себе и не парься.
                  Цитата Eric-S @
                  Объявил класс со статическими константами:
                  Скрытый текст
                  ExpandedWrap disabled
                    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)

                  ExpandedWrap disabled
                    switch( val )
                    {
                    case foo::alpha:
                    case foo::beta:
                    break;
                    default:
                    break;
                    }


                  Компилятор ms vs 2015 сказал, что foo::alpha не является константой!

                  а у меня все компилирует :D

                  пробовал vs2008

                  щас протестил в vs2010-vs2015 все компилирует :D :D

                  или я не правильно понял? :unsure:
                  Эриксон проправь меня, а то я с ума сойду :D
                  Сообщение отредактировано: Cfon -
                    Цитата Cfon @
                    Эриксон проправь меня, а то я с ума сойду :D

                    Ты разделил единицы трансляции? Должно быть два объектных файла: foo.obj и main.obj.

                    Добавлено
                    Цитата Олег М @
                    Ну а зачем ты выносишь тогда эти константы наружу? Сделай обертки для функций из этой библиотеки и все.

                    Как раз пишу статическую lib, в качестве обёртки.

                    Но в частности, эти константы нужны пользователю, для обработки callback функции.

                    Пользователь пишет функцию.
                    Регистрирует её в моей обёртке.
                    Затем библиотека дёргает эту функцию.
                    А пользователь должен обработат сообщение через switch.
                    Можно конечно if. Всё же функция простенькая, не какой-то там WinProc.

                    Добавлено
                    Цитата Олег М @
                    А вообще, это ж макросы. Просто скопируй их оттуда к себе и не парься.

                    Угу. Ну да... А хорошо ли так делать?

                    Подход гарантировано работающий сечас.
                    Но в будущем ломабельный. И просто неэтичный.

                    Добавлено
                    Цитата shm @
                    Цитата Eric-S @
                    Но ведь я и enum class могу изменить, с тем же успехом.

                    Не можешь.

                    Не... Я в том смысле, что если я изменю enum в одном файле, то придётся перекомпилировать все файлы, где используется этот enum.
                      Цитата Eric-S @
                      Я в том смысле, что если я изменю enum в одном файле, то придётся перекомпилировать все файлы, где используется этот enum.

                      Иии?
                        Цитата Славян @
                        Несколько странный вопрос. Ибо: компилирует, скажем, компилятор такой левый файл с таким левым switch'ем, а вы опосля взяли и переправили значение. В итоге - несогласованность. :oops:


                        Цитата Eric-S @
                        Замечание правомочно.
                        Но ведь я и enum class могу изменить, с тем же успехом.

                        Понятно, что такая ситуация возможно. Я о ней знаю.
                        Но неужели ничего нельзя поделать?


                        Значит всё равно придётся перекомпилировать! Единственная сложность в дополнительной проверки изменений.

                        Добавлено
                        Цитата shm @
                        Иии?

                        Да, нет. Ничо. Это я так, причетаю. Понятно же, что с enum, компилятору легче перепроверить кто когда изменился, поскольку enum открыт всем ветрам, опубликованный в хидере.
                        Сообщение отредактировано: Eric-S -
                          Цитата Eric-S @

                          Угу. Ну да... А хорошо ли так делать?

                          Подход гарантировано работающий сечас.
                          Но в будущем ломабельный. И просто неэтичный


                          В общем случае – нехорошо. А в частном – оцениваешь, стоит ли эта библиотека прилагаемых усилий, да еще в runtime. Чаще бывает, что проще скопировать значения.
                            Цитата Олег М @
                            В общем случае – нехорошо.

                            Потом будет лениво переделывать. Да и пользоватся странным интерфейсом стрёмно.
                            Так что, если делать, то максимально хорошо.
                            А в противном случае, проще юзать библиотеку, без всяких обёрток.
                              Цитата Eric-S @
                              Потом будет лениво переделывать. Да и пользоватся странным интерфейсом стрёмно.
                              Так что, если делать, то максимально хорошо.

                              Проблема в том, что ты пытаешься перенести в runtime решение задачи - сравнение и сопоставление констант - которая может и должна решаться в compile-time. В данном случае, если тебе очень не хочется выносить наружу заголовок твоей библиотеки, можно просто сделать свой enum или свои константы совпадающие по значению с библиотечными. И проверять где-нибудь их соответствие при помощи static_assert.
                                Вообщем я сделал свой enum class, с альтернативными кодами.
                                И две функции конвертирующие туда и обратно, через тот же самый switch.
                                Заодно, в секции default, воткнул throw invalid_argument.
                                Отработало всё нормально. Жаль, что моя версия компилятора не может это сделать constexpr, а в остальном результат устраивает.

                                Но если у кого появятся альтернативные решения, прошу отписаться!

                                Добавлено
                                Цитата Олег М @
                                можно просто сделать свой enum или свои константы совпадающие по значению с библиотечными. И проверять где-нибудь их соответствие при помощи static_assert.

                                Да! Это тоже хорошее, правильное решение.
                                Проверять через static_assert.
                                А приводить через reinterpret_cast?

                                Добавлено
                                Сейчас коммит оформлю, чтоб сохранить изменения с вариантом runtime. И попробую переделать с вариантом compile-time.
                                0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                0 пользователей:
                                Страницы: (3) [1] 2 3  все


                                Рейтинг@Mail.ru
                                [ Script execution time: 0,0549 ]   [ 17 queries used ]   [ Generated: 19.04.24, 07:30 GMT ]