Альтернативы C ++ статическим блокам Java

Я пишу класс даты, где я хочу, чтобы статическая карта отображала «Янв» на 1 и так далее. Мне интересно, как я могу инициализировать эту статическую карту. Это то, что я сейчас делаю, но я просто чувствую, что дополнительный оператор if неэлегантен по сравнению со статическим блоком в Java. Я понимаю, что компиляция программы на C ++ намного сложнее, но мне все еще интересно, существует ли лучшее решение.

class date {
    static map<string, int> month_map;
    int month;
    int year;
public:
    class input_format_exception {};
    date(const string&);
    bool operator< (const date&) const;
    string tostring() const;
};

map<string, int> date::month_map = map<string,int>();

date::date(const string& s) {
    static bool first = true;
    if (first)  {
        first = false;
        month_map["Jan"] = 1;
        month_map["Feb"] = 2;
        month_map["Mar"] = 3;
        month_map["Apr"] = 4;
        month_map["May"] = 5;
        month_map["Jun"] = 6;
        month_map["Jul"] = 7;
        month_map["Aug"] = 8;
        month_map["Sep"] = 9;
        month_map["Oct"] = 10;
        month_map["Nov"] = 11;
        month_map["Dec"] = 12;
    }   
    // the rest code.
}

// the rest code.

person user690421    schedule 06.05.2013    source источник
comment
Здесь есть связанный вопрос: http://stackoverflow.com/questions/138600/initializing-a-static-stdmapint-int-in-c Это может помочь вам понять ваши варианты.   -  person Matt    schedule 07.05.2013
comment
stackoverflow.com/questions/2172053/ также дает дополнительные подсказки.   -  person harpun    schedule 07.05.2013


Ответы (3)


Для систем, отличных от C ++ 11: как насчет использования вспомогательной функции и сделать month_map членом static const для date, поскольку похоже, что вы никогда не захотите изменить ассоциацию имени месяца с ним номер, а ты? Таким образом, month_map инициализируется в вашем cpp-файле, а не в вашем конструкторе, где он просто портит ситуацию. (Возможно, в будущем у вас будет несколько конструкторов, тогда вам придется писать много шаблонного кода)

const std::map<string, int> createMonthMap()
{
   std::map<string, int> result;

   // do init stuff

   return result;
}

const std::map<string, int> date::month_map(createMonthMap());
person xmoex    schedule 16.11.2013

В C ++ 11 вы можете использовать списки инициализаторов:

map<string, int> date::month_map = { {"Jan", 1},
                                     {"Feb", 2}
                                     // and so on
                                   };

В C ++ 03 я считаю, что вы застряли в том, что делаете в настоящее время.

person syam    schedule 06.05.2013
comment
На самом деле OP не зацикливается на том, что делает в настоящее время, кажется, мой ответ. Помимо этого предложения, я хочу проголосовать за вас ... - person einpoklum; 02.09.2016

Вы можете «реализовать» функцию статического блока в C ++, даже до C ++ 11. См. Мой подробный ответ здесь; это позволит вам сделать просто

#include "static_block.hpp"

static_block {
    month_map["Jan"] = 1;
    month_map["Feb"] = 2;
    month_map["Mar"] = 3;
    month_map["Apr"] = 4;
    month_map["May"] = 5;
    month_map["Jun"] = 6;
    month_map["Jul"] = 7;
    month_map["Aug"] = 8;
    month_map["Sep"] = 9;
    month_map["Oct"] = 10;
    month_map["Nov"] = 11;
    month_map["Dec"] = 12;
}   

Однако намного лучше использовать списки инициализаторов, поэтому, если у вас есть компилятор C ++ 11, используйте такие, как @ syam's предлагает ответ.

person einpoklum    schedule 02.09.2016