C++, может я статически инициализировать станд.:: карта во время компиляции?

Если я кодирую это

std::map<int, char> example = {
                                (1, 'a'),
                                (2, 'b'),
                                (3, 'c') 
                              };

затем g ++ говорит мне

deducing from brace-enclosed initializer list requires #include <initializer_list>
in C++98 ‘example’ must be initialized by constructor, not by ‘{...}’   

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

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

Но тем не менее мне любопытно - должен там так или иначе инициализировать карту, вектор, и т.д., во время компиляции?


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

Для Повышения я не уверен. Они слабы на использовании их классов Конечного автомата во встроенных системах, так, чтобы был на самом деле, что я кодирую здесь, классы Event/State/Fsm.

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

40
задан Mawg 30 May 2016 в 13:10
поделиться

7 ответов

не в C ++ 98. C ++ 11 поддерживает это, поэтому, если вы включите флаги C ++ 11 и включите то, что предлагает G ++, вы можете.

Редактировать: от GCC 5 C ++ 11 включен по умолчанию

21
ответ дан 27 November 2019 в 01:25
поделиться

Вы можете использовать BOOST.ASSIGN Библиотека:

#include <boost/assign.hpp>
#include <map>
int main()
{
   std::map<int, char> example = 
      boost::assign::map_list_of(1, 'a') (2, 'b') (3, 'c');
}

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

14
ответ дан 27 November 2019 в 01:25
поделиться

Это не совсем статическая инициализация, но все же, попробуйте. Если ваш компилятор не поддерживает C ++ 0x, я бы пошел на STD :: Map's итерационно-итерационный конструктор :

std::pair<int, std::string> map_data[] = {
    std::make_pair(1, "a"),
    std::make_pair(2, "b"),
    std::make_pair(3, "c")
};

std::map<int, std::string> my_map(map_data,
    map_data + sizeof map_data / sizeof map_data[0]);

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

37
ответ дан 27 November 2019 в 01:25
поделиться

С C ++ 0x, возможно, вам может потребоваться использовать брекеты (используйте синтаксис нового стиля для каждой пары):

std::map<int, char> example = { {1,'a'}, {2, 'b'}, {3, 'c'} };

Эти скобки для построения пар не имеют смысла. В качестве альтернативы вы можете полностью назвать каждую пару или использовать make_pair (как вы сделали в C ++ 98)

std::map<int, char> example = {
    std::make_pair(1,'a'),
    std::make_pair(2, 'b'),
    std::make_pair(3, 'c')
};

, что и для создания этих экземпляров при компиляции времени: нет. Контейнеры STL Все инкапсулируют полностью управление временем выполнения.

Я полагаю, вам действительно у вас только есть карта времени компиляции с библиотеками, такими как MetaProgramming Boost's MetaProgramm (не уверена, что не на 100%, если оно совсем правильно, и не изучалось, что это может быть хорошо для):

using namespace boost::mpl;
map<
    pair<integral_c<int, 1>, integral_c<char, 'a'> >,
    pair<integral_c<int, 2>, integral_c<char, 'b'> >,
    pair<integral_c<int, 3>, integral_c<char, 'c'> >
> compile_time_map;
13
ответ дан 27 November 2019 в 01:25
поделиться

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

typedef void (*VoidFunc)();
class Initializer
{
  public:
    Initializer(const VoidFunc& pF)
    {
      pF();
    }
};


, затем используйте это так:

std::map<std::string, int> numbers;
void __initNumsFunc()
{
  numbers["one"] = 1;
  numbers["two"] = 2;
  numbers["three"] = 3;
}
Initializer __initNums(&__initNumsFunc);


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

1
ответ дан 27 November 2019 в 01:25
поделиться

С предC++ 0x, самая близкая вещь, которую можно получить, не используя контейнеры, разработанные для использования во время выполнения (и ограничивая себя фундаментальными типами, и агрегируется) :

struct pair { int first; char second; };
pair arr[] = {{1,'a'}, {2,'b'}}; // assuming arr has static storage

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

, Конечно, вопрос состоит в том, выравнивают ли по ширине преимущества время, помещенное в реализацию этого.

, Если мое чтение корректно здесь, C++ 0x списки инициализатора может давать вам статическую инициализацию неагрегатов как станд.:: станд. карты и :: пара , но только если это не изменяет семантику по сравнению с динамической инициализацией.
Таким образом это кажется мне , можно только получить то, что вы попросили то, если ваша реализация может проверить через статический анализ, что поведение не изменяется, если карта статически инициализируется, но никакие гарантии, что это происходит.

4
ответ дан 27 November 2019 в 01:25
поделиться

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

Помните, однако, что STL - это просто спецификация интерфейса. Вы можете создавать свои собственные совместимые контейнеры и предоставить им статические возможности инициализации.

В зависимости от того, планируете ли вы обновить вашу реализацию Compiler и STL (особенно на встроенной платформе), вы можете даже просто копать в реализации, которую вы используете, добавляете полученные классы и используете их!

1
ответ дан 27 November 2019 в 01:25
поделиться
Другие вопросы по тегам:

Похожие вопросы: