На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
Модераторы: Qraizer, Hsilgos
  
> Инициализация std::map
    Всем привет! Наткнулся на детские грабли :-?

    Написал вот такое выражение, компилятор доволен:

    ExpandedWrap disabled
      typedef std::map<uint8_t, std::pair<uint8_t, uint8_t>> ScanMap;
       
      const ScanMap MapChars = {
          {0x01, {'1', '1'}}
      };

    Но если хочу написать вот так, то компилятор ругается, что типа нет такого конструктора для инициализации:

    ExpandedWrap disabled
      typedef std::map<uint8_t, uint8_t[2]>> ScanMap;
       
      const ScanMap MapChars = {
          {0x01, {'1', '1'}}
      };

    Можно как-то по второму варианту инициализировать константным выражением?
      Я себе вообще не представляют, как бы его можно инициализировать. Хоть константно, хоть динамично. Массив нельзя копировать и нельзя передать по значению. Он не класс, чтобы иметь конструктор из std::initializer_list<>. Его можно инициализировать только агрегатно, что несовместимо с неагрегатной инициализацией элементов std::map<> конструкторами. Я даже не представляю, как потом использовать такой std::map<>, ибо с его mapped_type будет невозможно ничего сделать.
      Если тебе нужен массив в контейнере, используй класс, а не POD. Т.е. std::array<>.
        Qraizer, вообще да - фигня получается с POD, что-то я притормозил.

        Цитата Qraizer @
        Если тебе нужен массив в контейнере, используй класс, а не POD. Т.е. std::array<>.

        Вообще-то там нужна пара uint8_t. Я сперва подумал с POD будет "дешевле" по обработке. Но потом да, ты прав, хрен знает
        как это потом использовать. Останусь с std::pair.
          Тут проблема не столько в том, что это POD, сколько в том, что контейнеры требуют от своих элементов соответствия семантики значения, тогда как сырые массивы это требование нарушают. Скажем, к структурам ты смог бы применить этот подход, если б захотел. Тот же std::pair<>, к примеру, тоже просто структура, с конструкторами разве что.
            Да да, я уже осознал.
              PS. Хотя как-то неловко, объявить typedef map<uint8_t,uint8_t[2]> Map; можно, а использовать нельзя :-?
                Можно попробовать обернуть массив в класс. Сделать инициализатор, и реализовать оператор []. Снаружи должно выглядеть в точности как использование массива из двух чисел.
                Только это вроде бы и есть в точности то, что делает std::array.
                  Цитата amk @
                  Только это вроде бы и есть в точности то, что делает std::array

                  Да ... и то же что std::pair. На счет использования - понятно. А вот почему объявление допустимо - странности.
                    Завезут концепты, тогда можно будет проверять контракты типов. Нынче же uint8_t[2] суть просто тип, а что он умеет и чего не умеет, определится только при попытке сие использовать в программе.
                    Вообще говоря, кое-что и сейчас можно напроверять, писали же раньше метапрограммы без <type_traits>. Только муторно это, и не место подобному в Стандартной библиотеке.
                      Цитата Qraizer @
                      Только муторно это, и не место подобному в Стандартной библиотеке.

                      Ну пока один вывод - не все так гладко в датском королевстве :-?
                        И как всегда в подобных случаях, когда в Плюсах в что-то вызывает вопросы корректности его философии – альтернатива была бы хуже, JoeUser.
                        Сообщение отредактировано: Qraizer -
                        0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                        0 пользователей:


                        Рейтинг@Mail.ru
                        [ Script execution time: 0,0289 ]   [ 16 queries used ]   [ Generated: 25.04.24, 07:53 GMT ]