Tell me more ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I am trying to write a calculation intensive program. And I need char* to be the fields of comparsion for the composite_key_compare of the multi_index_container. However, it doesn't seem to work. Code as below:

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

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

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,
                composite_key_compare
                <equal_char, equal_char> 
            >
        >
    > MyContainer;

boost::ptr_vector<MyStruct> vec;
MyStruct* struct1=new MyStruct();
struct1->firstName="Michael";
struct1->secondName="Mike";
struct1->age=20;
vec.push_back(struct1);



MyContainer myContainer;
myContainer.insert(struct1);
char* first="Michael";
char* second="Mike";
auto it=myContainer.find(boost::make_tuple(first, second));
if(it!=myContainer.end())
    cout << (*it)->age << endl;

I did trace into the equal_char, and found out it did return true on the first comparison of "Michael" to "Michael", but I also found that the equal_char is not called for the second comparsion of "Mike" to "Mike". Anyone who can help me with this? How sould I write the composite_key_compare?

share|improve this question

1 Answer

I traced the program, and found out that boost expects something like std::less() for the compare operation for "ordered unique".

So, I added below code, and it worked.

struct CompareLess
{   // functor for operator<=
#pragma region For 1 variable
    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;
    }

#pragma endregion For 1 variable
#pragma region For 2 variables
    static inline int compare(const boost::multi_index::composite_key_result<comp_key>& k, const boost::tuple<char*, char*>& y)
    {
        int val=strcmp(k.value->firstName, y.get<0>());
        if(val!=0)
            return val;
        else
            return compare(y.get<1>(),(const char*)(k.value->secondName));
    }
    inline bool operator()(const boost::multi_index::composite_key_result<comp_key>& k, const boost::tuple<char*, char*>& y) const
    {
        return compare(k,y) <0;
    }

    static inline int compare(const boost::tuple<char*, char*>& y, const boost::multi_index::composite_key_result<comp_key>& k)
    {
        return -compare(k,y);
    }
    inline bool operator()(const boost::tuple<char*, char*>& y, const boost::multi_index::composite_key_result<comp_key>& k) const
    {
        return compare(y,k)<0;
    }
#pragma endregion For 2 variables
#pragma region For all variables
    inline bool operator()(const boost::multi_index::composite_key_result<comp_key>& k1, 
        const boost::multi_index::composite_key_result<comp_key>& k2) const
    {
        return CompareLess()((const char*)(k1.value->firstName), (const char*)(k2.value->firstName));
    }
#pragma endregion For all variables



};

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

But I got more question, this is very lengthy code, and suppose if I have more fields, it is going to be much much more longer. Is there any smart way to do this?

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.