2

異なるフィールドで比較する 1 つのコンパレータを作成するにはどうすればよいですか。フィールドごとに異なるタイプ (uintまたはstring) を持つことができます。使用する必要がありますT *か?

コード長を短くする必要があります。

template<typename T>
class ComparatorSelector
{
public:
    struct CompareByLabel{
        bool operator() ( const T & iRight, const T & iLeft )
        {
            return iRight->m_label > iLeft->m_label;
        }
    };
    struct CompareByHouseNumber{
        bool operator() ( const T & iRight, const T & iLeft )
        {
            return iRight->m_houseNumber > iLeft->m_houseNumber;
        }
    };
    //...
};


template< class T, class C, typename W >
class SearchIndex
{
public:
    SearchIndex() {}

    void Build( std::vector< T > iElems, C iComparator, std::ofstream oStream )
    {
        std::map< T *, size_t> numbersOfElems;

        for( class std::vector<T>::iterator it = iElems.begin(); it != iElems.end(); ++it){
            m_elems.insert( &(*it));
            numbersOfElems[&(*it)] = m_elems.end - it ;
        }

        oStream << m_elems.size();
        for( class std::multiset< T * >::iterator it = m_elems.begin(); it!= m_elems.end(); ++it )
            oStream << numbersOfElems[*it];

        m_compareMode = iComparator;
    }
//....
}
4

2 に答える 2

2

メンバーへのポインタを使用して、コンパレータ オブジェクトをカスタマイズできます。より遅いがより単純なアプローチは次のとおりです。

#include <iostream>

template <typename Type, typename Class>
class comparator
{
    Type Class::*d_member;
public:
    comparator(Type Class::*member): d_member(member) {}
    bool operator()(Class const& object0, Class const& object1) const {
        return object0.*(this->d_member) < object1.*(this->d_member);
    }
};

template <typename Type, typename Class>
comparator<Type, Class>
make_comparator(Type Class::*member)
{
    return comparator<Type, Class>(member);
}

int main()
{
    typedef std::pair<int, double> pair;
    pair p0(17, 3.14);
    pair p1(42, 2.7);
    std::cout << std::boolalpha
              << "first: " << make_comparator(&pair::first)(p0, p1) << ' '
              << "second: " << make_comparator(&pair::second)(p0, p1) << ' '
              << '\n';
}

このバージョンは実行時にメンバーへのポインターを使用するため、簡単にインライン化することはできず、期待するほど高速ではありません。メンバーは、コンパレーターの型に埋め込むこともできます。これにより、両方の使用が少し面倒になります。

template <typename Type, typename Class, Type Class::*Member>
class comparator
{
public:
    bool operator()(Class const& object0, Class const& object1) const {
        return object0.*Member < object1.*Member;
    }
};

int main()
{
    typedef std::pair<int, double> pair;
    pair p0(17, 3.14);
    pair p1(42, 2.7);
    std::cout << std::boolalpha
              << "first: " << comparator<int, pair, &pair::first>()(p0, p1) << ' '
              << "second: " << comparator<double, pair, &pair::second>()(p0, p1) << ' '
              << '\n';
}
于 2013-08-24T10:14:55.890 に答える