I am trying to do something like Java Enum, which I call a flag. The requirements are that each flag is static, so the flags have a direct link, each flag stores the name string and the whole set of iterations and helps the search.
I use templates, so that each set of flags is stored separately (this way, I do not want to explicitly place the set in each child class).
I am convinced that this is an initiation problem, because the success or failure of starting the program depends on the file name of the object containing the flag declarations (Ao segfaults, but Zo works fine.)
The problem, apparently, is one of the static orders of initialization, this code compiles fine, but when it starts, gdb produces the following:
Program received signal SIGSEGV, Segmentation fault. 0x00007ffff751e0fa in std::_Rb_tree_decrement(std::_Rb_tree_node_base*) () from /usr/lib/gcc/x86_64-pc-linux-gnu/4.4.5/libstdc++.so.6 (gdb) bt #0 0x00007ffff751e0fa in std::_Rb_tree_decrement(std::_Rb_tree_node_base*) () from /usr/lib/gcc/x86_64-pc-linux-gnu/4.4.5/libstdc++.so.6 #1 0x0000000000462669 in operator-- () at /usr/lib/gcc/x86_64-pc-linux-gnu/4.4.5/include/g++-v4/bits/stl_tree.h:199 #2 _M_insert_unique () at /usr/lib/gcc/x86_64-pc-linux-gnu/4.4.5/include/g++-v4/bits/stl_tree.h:1179 #3 insert () at /usr/lib/gcc/x86_64-pc-linux-gnu/4.4.5/include/g++-v4/bits/stl_set.h:411 #4 Flag () at include/../util/include/Flag.hpp:34
My code is as follows:
template <class FlagType> class Flag { public: Flag(int ordinal, String name): ordinal(ordinal), name(name) { flagSet.insert(this); } inline bool operator==(const Flag<FlagType>& e) const { //edited due to comment //if(this->ordinal == e.getOrdinal()) return true; //else return false; return (this->ordinal == e.getOrdinal()); } inline bool operator!=(const Flag<FlagType>& e) const { return !(*this==e); } static const std::set<const Flag<FlagType>*>& flagValues() { return flagSet; } const String& toString() const { return name; } const size_t& getOrdinal() const { return ordinal; } static int size() { return flagSet.size(); } static const Flag<FlagType>& valueOf(const String& string) { typename std::set<const Flag<FlagType>*>::const_iterator i; for(i = flagSet.begin(); i != flagSet.end(); i++) { if((**i).toString().startsWith(string)) { return **i; } } throw NotAFlagException(); } protected: static std::set<const Flag<FlagType>*> flagSet; size_t ordinal; String name; private: //added in response to comment to prevent copy and assignment, not compile tested Flag<FlagType>(const Flag<FlagType>&); Flag<FlagType>& operator=(const Flag<FlagType>&); }; template <class FlagType> std::set<const Flag<FlagType>*> Flag<FlagType>::flagSet; //template
Item.hpp
class ItemFlag: public Flag<ItemFlag> { public: static const ItemFlag brick; private: ItemFlag(int ordinal, String name): Flag<ItemFlag>(ordinal, name){} };
Item.cpp
const ItemFlag ItemFlag::brick(1, "brick");
My first post, so please let me know if I have the wrong formatting or was non-specific. PS. with curiosity, replacing the set with vector results in the work program, as if the set had problems inserting pointers. To test this, I replaced the set with the set int and tried to insert 0 into the initialization of the class, this also led to the same error.