3

I am writing a date class where I want a static map to map "Jan" to 1 and so on. I am wondering how I can initialize that static map. This is what I am currently doing, but I just feel that the extra if statement is inelegant compared with static block in Java. I understand the compilation of C++ program is much more complicated, but I still wonder whether a better solution exists.

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.
einpoklum
  • 118,144
  • 57
  • 340
  • 684
user690421
  • 422
  • 1
  • 5
  • 15
  • 2
    There's a related question here: [http://stackoverflow.com/questions/138600/initializing-a-static-stdmapint-int-in-c](http://stackoverflow.com/questions/138600/initializing-a-static-stdmapint-int-in-c) That might help you understand your options. – Matt May 06 '13 at 22:19
  • http://stackoverflow.com/questions/2172053/c-can-i-statically-initialize-a-stdmap-at-compile-time also gives additional hints. – harpun May 06 '13 at 22:31

3 Answers3

6

In C++11 you can use initializer lists:

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

In C++03 I believe you're stuck with what you are currently doing.

syam
  • 14,701
  • 3
  • 41
  • 65
  • Actually, OP isn't stuck with what s/he is currently doing, seem my answer. Other than that sentence I want to upvote you... – einpoklum Sep 02 '16 at 18:07
1

For non-c++11 systems: how about using a helper function and make month_map a static const member of date as it looks like you never wan't to change the association of the month's name with it's number, do you? This way month_map is initialized in your cpp-File and not in your constructor where it just messes things up. (Maybe you'll have several constructors in the future then you'll have to write a lot of boilerplate code)

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());
xmoex
  • 2,602
  • 22
  • 36
0

You can "implement" a static block feature in C++, even pre-C++11. See my detailed answer here; it will let you do simply

#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;
}   

However, it is much better to use initializer lists, so if you have a C++11 compiler, do use those like @syam's answer suggests.

einpoklum
  • 118,144
  • 57
  • 340
  • 684