2013-11-09 3 views
0

Предположим, что у нас есть имя класса Default, у которого есть два атрибута x и y.
Операция по умолчанию для сравнения объекта использует атрибут x.Перегрузка оператора и литье типов

Когда мы хотели бы сравнить этот объект с помощью другого атрибута у,
1. Безопасно ли создавать новый Dérivé класса, который может сравнить с помощью атрибута у, а затем литья указателя от умолчанию для этого нового класса и сравнить объект ?
2. Каков альтернативный способ сделать это без снижения эффективности работы?

Требование состоит в том, что мы не можем изменить подпись алгоритма сортировки для передачи указателя функции на разностный компаратор.

Кстати, этот метод не требует затрат на преобразование или копирование данных.

class Default {public:int x; int y;}; 

class Compare1 : public Default {}; 

bool operator < (const Default &left,const Default &right) 
{ 
    return left.x < right.x; 
} 
bool operator < (const Compare1 &left,const Compare1 &right) 
{ 
    return left.y < right.y; 
} 

template<typename T> 
int *sort_element(const T *data, int size) 
{ 
    int *permute; 
    //... do some sorting by using < comparator ... 
    return permute; 
} 

int main(){ 
    Default *obj; 
    int obj_size; 
    //… initialize obj and obj size.. 

    // sorting object with default order. 
    int *output_default = sort_element(obj, obj_size) 

    // sorting with customize comparator. 
    Compare1 *custom1 = static_cast<Compare1*>(obj); 
    int *output_custom1 = sort_element(custom1, obj_size); 
} 

ответ

2

Лучше передать функтор или лямбду в качестве функции сравнения, когда вы их сортируете. Ваша функция сортировки должна принять функцию:

template<typename T, typename F> 
int *sort_element(const T *data, int size, F comp) 
{ 

    .... 

    if (comp(a, b)) 
     .... 

    ... 
} 

Тогда

// Sort by x 
sort_element(..., [](const Default &a, const Default &b) { 
     return a.x < b.x; 
    }); 

// Sort by y 
sort_element(..., [](const Default &a, const Default &b) { 
     return a.y < b.y; 
    }); 

Если вы не C++ 11 вы можете использовать функциональный объект (функтор) вместо:

struct fx 
{ 
    bool operator()(const Default &a, const Default &b) const 
    { 
     return a.x < b.x; 
    } 
}; 

struct fy 
{ 
    bool operator()(const Default &a, const Default &b) const 
    { 
     return a.y < b.y; 
    } 
}; 

// Sort by x 
sort_element(..., fx()); 

// Sort by x 
sort_element(..., fy()); 

Забудьте ваш второй класс Compare1 и снимите его.

+0

Звучит неплохо, но есть случай, когда я не могу изменить заголовок функции sort_element. – unbound

+0

Если вы не можете, к сожалению, у вас нет выбора, ваш код будет единственным вариантом, тогда вы должны перестать беспокоиться об эффективности. – deepmax

Смежные вопросы