Копирование / назначение шаблонов STL, std :: less и std: great - PullRequest
1 голос
/ 09 августа 2011

Мне нужно выбрать между шаблонами std :: less и std :: большее и сохранить один в другом шаблоне (я думаю, что я использую словарь C ++ STL, верно ..?). У меня есть это:

template<typename> class stSortOrder;
stSortOrder = std::less;
if(sortby == "descending")
    {
    stSortOrder = std::greater;
    }

Очевидно, что он не компилируется. Я уверен, что это потому, что я относительный новичок в STL.


РАЗЪЯСНЕНИЯ:

Я реализую принятый ответ в этой теме (вариант для открытых функций-членов).

Вот что я хочу избежать в случае переключателя:

void CSubscriptionItem::sortMonitoredItems( int nColumnIndex, Qt::SortOrder ulOrder )
    {
    switch(nColumnIndex)
        {
        case CMonitoredItem::NAME:
            {
            if(ulOrder == Qt::DescendingOrder)
                {
                qSort(  m_qlpcMonitoredItems.begin(), 
                        m_qlpcMonitoredItems.end(), 
                        make_method_comparer<std::less>(&CMonitoredItem::getName) );
                }
            else
                {
                qSort(  m_qlpcMonitoredItems.begin(), 
                        m_qlpcMonitoredItems.end(), 
                        make_method_comparer<std::greater>(&CMonitoredItem::getName) );
                }
            break;
            }

Я бы хотел заменить std :: less и std :: большее в make_method_comparer <> одним шаблоном, который уже настроен в зависимости от аргумента порядка сортировки. Это действительно поможет уменьшить размер кода.

Я рассмотрел оба опубликованных ответа, но, похоже, они не работают - скорее всего потому, что я не слишком знаком с шаблонами и просто неправильно их использую.

Ответы [ 3 ]

2 голосов
/ 09 августа 2011

Можно сделать:

template <typename T>
struct comparer
{
    comparer(bool is_less) : is_less(is_less) {}

    bool operator()(const T& x, const T& y) const
    {
        return is_less ? std::less<T>()(x, y) : std::greater<T>()(x, y);
    } 

private:
    bool is_less;
};

, но я бы предпочел сделать (более четко):

template <typename T>
struct comparer
{
    bool operator()(const T& a, const T& b) const
    {
        return is_less ? a < b : b < a;
    }

private:
    bool is_less;
};
2 голосов
/ 10 августа 2011

Если ваш компилятор поддерживает TR1, вы можете просто:

std::vector<int> v = { 3, 9, 17, 12, 5, 4 }; // NOTE: C++0x initialiser
const bool ascending = true;
typedef std::tr1::function<bool(int, int)> sort_func;
sort_func& func = ascending
    ? static_cast<sort_func>(std::less<int>())
    : static_cast<sort_func>(std::greater<int>());
std::sort(v.begin(), v.end(), func);

Или, если у вас есть повышение, заменить std::tr1::function на boost::function.

2 голосов
/ 09 августа 2011

Вам понадобится вспомогательный класс для решения этой проблемы во время выполнения, сделайте что-то вроде:

template <typename T>
class ChosedSorter {
public:
    ChosedSorted(bool descending) : _d(descending)
    {
    }
    bool operator()(const T& a, const T& b) {
        if( _d )
            return _less(a,b);
        return _greater(a,b);
    }
private:
    bool _d;
    std::less<T> _less;
    std::greater<T> _greater;
}

И тогда вы используете это так:

void CSubscriptionItem::sortMonitoredItems( int nColumnIndex, Qt::SortOrder ulOrder )
    {
    switch(nColumnIndex)
        {
        case CMonitoredItem::NAME:
            {
            ChosedSorted<QString> sorter(ulOrder == Qt::DescendingOrder);
                std::sort(  m_qlpcMonitoredItems.begin(), 
                        m_qlpcMonitoredItems.end(), 
                        sorter);
            break;
            }
// ...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...