Choosing a STL container with uniqueness and which keeps insertion ordering

后端 未结 8 2087

I am unable to decide which STL container to use in the following case:

  1. I want to preserve the order of insertion of the elements
  2. The elements in the
8条回答
  •  忘掉有多难
    2021-01-18 01:28

    Well, i once had a similar situation. One thing that came in my mind was 'can i use multi-keys'? I googled for a while, and found a sample using std::set. So, if you do not have access to boost (i recommend it, there is no point re-inventing the wheel); you can try something like the below example. I think you can use the secondary key as the position of insertion (auto-increment). From the example that i found on internet; i tailored it for my needs. This one is a modified version of the same.

    Cavaet: It is using macros. I know they are evil in general, but this use is o.k. i guess.

    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    
    #define MULTIKEYDEF(NAME,TYPE) \
        inline TYPE const & NAME() const { return d_##NAME; } \
        inline void NAME(TYPE const & t) { d_##NAME = t; } \
        TYPE d_##NAME; \
    class T##NAME \
        : public std::unary_function { \
    private: \
        TYPE d_compare; \
    public: \
        T##NAME(TYPE t) : d_compare(t) {} \
        T##NAME(T##NAME const & self) \
        : d_compare(self.d_compare) {} \
        bool operator()(Tmultikey * mk) { \
        return d_compare == mk->##NAME(); \
        } \
       inline TYPE const& name() const { return d_compare; } \
        }
    
    class Tmultikey {
    public:
        // Actual keys
        // Can be accessed through d_primary and d_secondary,
        // or primary() and secondary()
        MULTIKEYDEF(primary , std::string);
        MULTIKEYDEF(secondary, unsigned int);
        // Mandatory
        bool operator < (Tmultikey const& mk) const {
            if(primary() < mk.primary()) return true;
            else if(primary() == mk.primary()) {
                return secondary() < mk.secondary();
            }
            return false;
        }
        // Constructor
        Tmultikey(std::string p, unsigned int s)
            : d_primary(p), d_secondary(s) {}
    
        // Eraser for std::set
        template
            static void erase(std::set & c, Compare op) {
                typename std::set::iterator pos = c.begin();
                while(pos != c.end()) {
                    if(op(&(*pos))) {
                        c.erase(pos++);
                    } else ++pos;
                }
            }
          // Eraser for std::set
          template
          static std::set::iterator find_ex(std::set & c, Compare op) {
             typename std::set::iterator pos = c.begin();
             while(pos != c.end()) {
                if(op(&(*pos))) {
                   break;
                } else ++pos;
             }
             return pos;
          }
    };
    
    int main(int argc, char* argv[])
    {
        std::set mkset;
    
        mkset.insert(Tmultikey("1",5));
        mkset.insert(Tmultikey("6",4));
        mkset.insert(Tmultikey("3",7));
        mkset.insert(Tmultikey("1",6));
    
       std::set::iterator bg = mkset.begin();
       for (;bg != mkset.end(); ++bg)
       {
          std::cout<<(*bg).primary()<

    HTH,

提交回复
热议问题