С++ - эквивалент неполностью инициализированных массивов в C?

Когда я преобразовываю код из C в С++, я иногда сталкиваюсь с языковыми конструкциями, которые являются C, но совместимыми с С++. Обычно я хочу преобразовать код в наименее навязчивый способ. Но у меня есть один случай, когда я нахожу это очень трудным:

В C вы можете объявить массив и инициализировать... хорошо... части, используя "указатели", остальные обнуляется (Edit: я написал "слева на случайность" здесь, сначала):

int data[7] = {
    [2] = 7,
    [4] = 9,
};

Это недопустимый код С++, хотя (к счастью). Поэтому мне придется использовать другую стратегию.

Пока я вижу неинтрузивный способ в С++ 11:

static const map<int,int> data = { {2,7}, {4,9} };

что делать, если возможности С++ 11 еще недоступны?

  • Можно ли обойти инициализацию времени выполнения?
  • Есть ли способ инициализировать аналогичный вид отображения в "литерале" ?
  • Что означает наименее навязчивый код, который использует data?

Ответы

Ответ 1

Если стандартная инициализация недоступна, std::map<int, int> может быть инициализирован с помощью boost::assign::map_list_of:

#include <boost/assign/list_of.hpp>
static const std::map<int,int> data = boost::assign::map_list_of(2,7)(4,9);

Ответ 2

Хорошо, если размер массива не сумасшедший, вы всегда можете сделать это

int data[7] = {
    0,
    0,
    7, // #2
    0, 
    9  // #4
    // the rest will be 0-initialized
};

Работает также во время компиляции

Ответ 3

Вместо использования map<int, int> вы можете выполнить backport std:array (или минимальный эквивалент) из С++ 11 и использовать средство построения стиля Buost.Assign:

#include <cstddef>

template<typename T, size_t N> struct array { T data[N]; };
template<typename T, size_t N> struct build_array: public array<T, N> {
   build_array &operator()(size_t i, const T &t) {
      this->data[i] = t;
      return *this;
   }
};

array<int, 7> data_array = build_array<int, 7>()(2, 7)(4, 9);
int (&data)[7] = data_array.data;

Ответ 4

Почему вы не можете сделать:

int data[7];
data[2] = 7;
data[4] = 9;

выглядит очень-очень похоже =)

Ответ 5

Если вы не хотите использовать boost::assign Вы можете создать простой аналог:

template<class T1, class T2>
std::map<T1, T2> cre(std::map<T1, T2> & m)
{
   return std::map<T1, T2>();
}

template<class T1, class T2>
std::map<T1, T2> & ass(std::map<T1, T2> & m, T1 const & p1, T2 const & p2)
{
   m[p1] = p2;
   return m;
}

std::map<int, int> data = ass(ass(cre(data), 2, 3), 7, 6);