0

For below code:

struct MyStruct
{
    char* firstName;
    char* secondName;
    int age;
};

typedef composite_key
    <MyStruct*,
    BOOST_MULTI_INDEX_MEMBER(MyStruct, char*, firstName),
    BOOST_MULTI_INDEX_MEMBER(MyStruct, char*, secondName)
    > comp_key;

typedef multi_index_container
    <
    MyStruct*, 
    indexed_by
        <
        ordered_unique
            <
                comp_key,
                CompareLess
            >
        >
    > MyContainer;

I can easily write a compareless, like below:

struct CompareLess
{   // functor for operator<
    static inline int compare(const char* left, const char* right)
    {
        return strcmp(left, right);
    }
    inline bool operator()(const char* left, const char* right) const
    {   // apply operator<= to operands
        return compare(left, right)<0;
    }

    static inline int compare(const boost::tuple<char*>& x, const char*y)
    {
        return compare(x.get<0>(),y);
    }
    inline bool operator()(const boost::tuple<char*>& x, const char*y) const
    {
        return compare(x,y)<0;
    }

    static inline int compare(const boost::multi_index::composite_key_result<comp_key>& k, const boost::tuple<char*>& y)
    {
        return -compare(y,(const char*)(k.value->firstName));
    }
    inline bool operator()(const boost::multi_index::composite_key_result<comp_key>& k, const boost::tuple<char*>& y) const
    {
        return compare(k,y)<0;
    }

    static inline int compare(const boost::tuple<char*>& y, const boost::multi_index::composite_key_result<comp_key>& k)
    {
        return compare(y,(const char*)(k.value->firstName));
    }
    inline bool operator()(const boost::tuple<char*>& y, const boost::multi_index::composite_key_result<comp_key>& k) const
    {
        return compare(y,k) <0;
    }
}

But when I want to write something like below:

typedef composite_key
    <double,
    char*,
    char*
    > comp_key;

I have trouble writing the compareLess with the below function

    static inline int compare(const boost::tuple<char*>& y, const boost::multi_index::composite_key_result<comp_key>& k)
    {
        return compare(y,(const char*)(k.value->firstName));
    }

I don't know how to write some code as "k.value->firstName" to get the char* for comparsion, since the value is no longer a struct, it is only a double. So where can I get the field for comparison? is there something like k.get<0>()?

TemplateRex
  • 69,038
  • 19
  • 164
  • 304
Michael
  • 673
  • 2
  • 5
  • 23

1 Answers1

1

Composite keys' comparison criteria are specified via composite_key_compare. In your particular case you'd want something like

ordered_unique<
  comp_key,
  composite_key_compare<
     std::less<double>,
     CompareLess,
     Compareless
  >
>

where CompareLess needs only be callable with const char*s:

struct CompareLess
{   
    static inline int compare(const char* left, const char* right)
    {
        return strcmp(left, right);
    }
    inline bool operator()(const char* left, const char* right) const
    {
        return compare(left, right)<0;
    }
};

The rest of the scaffolding is provided by composite_key_compare.

Joaquín M López Muñoz
  • 5,243
  • 1
  • 15
  • 20
  • Thank you very much. It saved me a lot of effort typing. But I have a second issue, which is how can I insert a record into such a container? myContainer.insert(make_tuple(...))? – Michael Jul 16 '13 at 15:56
  • You have to insert whole elements (MyStruct's in this case), not only the keys. – Joaquín M López Muñoz Jul 17 '13 at 04:29
  • Thank you. I mean what can I do to insert data if I replace MyStruct with 'double'? I don't want to construct too many MyStructs when I already have vector firstName and vector secondNames, since deleting of these structs takes time... – Michael Jul 18 '13 at 11:56