увеличить multi_index_container композитный_key_compare

Я пытаюсь написать программу интенсивного расчета. И мне нужно, чтобы char* был полями сравнения для component_key_compare multi_index_container. Однако, похоже, это не работает. Код, как показано ниже:

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;

Я проследил до equal_char и обнаружил, что он возвращает true при первом сравнении "Michael" с "Michael", но я также обнаружил, что equal_char не вызывается для второго сравнения "Mike" с "Mike". Любой, кто может помочь мне с этим? Как мне написать композитный_ключ_компаре?


person Michael    schedule 13.07.2013    source источник


Ответы (1)


Я проследил программу и обнаружил, что boost ожидает что-то вроде std::less() для операции сравнения для «упорядоченного уникального».

Итак, я добавил ниже код, и это сработало.

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;

Но у меня есть еще вопрос, это очень длинный код, и предположим, что если у меня будет больше полей, он будет намного длиннее. Есть ли какой-нибудь умный способ сделать это?

person Michael    schedule 16.07.2013