2011-02-07 3 views
3

Как связать оператор преобразования с bool с помощью boost :: bind или boost :: lambda?C++ boost :: bind/lambda и operator bool()

Например, предположим, что у меня есть класс C, с оператором bool() и list<C>. Как использовать remove_if и bind/lambda для удаления всех элементов, которые при преобразовании в bool оцениваются как false?

ответ

5

Для этого вам не нужно использовать std::bind или std::remove_if; std::remove будет достаточно:

std::vector<T> v; // Assuming T provides some conversion to bool 

// Remove all elements that evaluate to 'false': 
v.erase(std::remove(v.begin(), v.end(), false), v.end()); 

Или, вы можете использовать std::logical_not функциональный объект с std::remove_if:

v.erase(std::remove_if(v.begin(), v.end(), std::logical_not<T>()), v.end()); 

Это очень редкое, что класс должен реализовать фактическую operator bool() перегрузки: из-за проблем с C++ система, обеспечивающая такое преобразование, позволяет очень ошибочно ошибочно писать неправильный код, который использует преобразование, в котором вы не ожидаете его использования. Намного лучше реализовать идиому safe-bool вместо фактической перегрузки operator bool(). Недостатком этого является то, что вы не можете привязываться к перегрузке operator bool(), так как идиома safe-bool полагается на преобразование в некоторый неопределенный тип.

+0

Обратите внимание, что существует различие между 'remove' подходом и' remove_if' подходом: 'remove' подход основан на использовании' оператора = = 'и не будет работать для типов, явно не сопоставимых с равенством. Например, подход 'remove' не будет работать для ряда объектов' std :: function', но подход 'remove_if', который опирается только на использование' operator! ', Будет работать нормально. [Я отредактирую это в свой ответ в какой-то момент.] –

+0

Спасибо. Вы правы, что в этом случае удаление (вместо remove_if) - самый простой подход. Использование logical_not также работает; было бы еще лучше, если бы T был как-то автоматически выведен компилятором, но хорошо. – imre

+1

@imre: В этом случае довольно легко написать собственный объект функции, который не требует аргумента шаблона: 'struct awesome_not {template bool operator() (const T & x) {return! X; }}; '[Я также отредактирую это в своем ответе в конце концов.] –

0

использовать std :: logical_not, если вам нужно удалить, если оператор оценивает значение false; если вам нужно удалить, если так, то вы можете использовать:

remove_if(..., ..., bind(&C::operator bool, _1)); 
Смежные вопросы