Есть что-нибудь вроде "std :: and" или "std :: or"? - PullRequest
21 голосов
/ 28 июня 2011

Учитывая контейнер логических значений (например, std::vector<bool>), есть ли стандартная функция, которая возвращает true, если все значения true ("и") или true, если хотя бы одно значениеэто true ("или"), с оценкой короткого замыкания?

Я выкопал корыто www.cplusplus.com сегодня утром, но не смог найти ничего близкого.

Ответы [ 4 ]

43 голосов
/ 28 июня 2011

существует ли стандартная функция, которая возвращает истину, если все значения верны ("и")

std::all_of(vec.begin(), vec.end(), [](bool x) { return x; } )

или истина, если хотя бы одно значение истинно ("или")

std::any_of(vec.begin(), vec.end(), [](bool x) { return x; } )

с оценкой короткого замыкания?

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

37 голосов
/ 28 июня 2011

Вы можете реализовать:

И

std::find(vector.begin(), vector.end(), false) == vector.end() // all the values are true

OR

std::find(vector.begin(), vector.end(), true) != vector.end() //at least one value is true
10 голосов
/ 28 июня 2011

Вы можете использовать функциональные объекты logical_and и logical_or в сочетании с сокращением для достижения этой цели.

accumulate рассчитывает сокращение.Следовательно:

bool any = std::accumulate(foo.begin(), foo.end(), false, std::logical_or);
bool all = std::accumulate(foo.begin(), foo.end(), true, std::logical_and);

Предостережение: это , а не с использованием короткого замыкания (функция accumulate ничего не знает о коротком замыкании, хотя это делают функторы), в то время как хитрое решение Игоря.

1 голос
/ 28 июня 2011

Если вам не нужен универсальный алгоритм для разных типов контейнеров ...

Поскольку вы ищете оценку короткого замыкания, вы можете дать std :: valarray шанс. Для and используйте valarray::min() == true для or, вы можете использовать std::find, как упомянул Игорь.

Если вы знаете количество элементов, которые нужно сохранить во время компиляции, вы можете даже использовать std :: bitset:

bitset<100> container();

//... fill bitset

bool or = container.any();
bool and = container.count() == container.size();
...