Given a container of boolean values (An example is std::vector<bool>), is there a standard function that returns true if all the values are true ("and") or true if at least one value is true ("or"), with short circuit evalutation ?
I digged trough www.cplusplus.com this morning but couldn't find anything close.
is there a standard function that returns true if all the values are true ("and")
std::all_of(vec.begin(), vec.end(), [](bool x) { return x; } )
or true if at least one value is true ("or")
std::any_of(vec.begin(), vec.end(), [](bool x) { return x; } )
with short circuit evalutation?
I just inserted print statements into the lambda, and yes, both functions perform short-circuiting.
You can implement by:
AND:
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
You can use the function objects logical_and and logical_or in conjunction with a reduction to accomplish that.
accumulate calculates the reduction. Hence:
bool any = std::accumulate(foo.begin(), foo.end(), false, std::logical_or<>());
bool all = std::accumulate(foo.begin(), foo.end(), true, std::logical_and<>());
Caveat: this is not using short-circuiting (the accumulate function knows nothing about short-circuiting even though the functors do), while Igor’s clever solution is.
If you do not need a generic algorithm for different container types...
As you are looking for short circuit evaluation, you may give std::valarray a chance. For and use valarray::min() == true for or you could use std::find as mentioned by Igor.
In case you know the number of elements to store at compile time, you could even use a std::bitset:
bitset<100> container();
//... fill bitset
bool or = container.any();
bool and = container.count() == container.size();
Related
I am trying to use for each loop in c++.
this->Functions is a vector.
std::vector< std::shared_ptr<Sum_Function> > Functions;
After reading i came across two different ways to do for each.
bool Container::HasFunction(std::string stdstrFunctionName )
{
for (auto &func : this->Functions)
{
if (func->getFunctionName() == stdstrFunctionName)
return true;
}
return false;
}
///////////////////////////////////////////////////////////////////////////////////
bool Container::HasFunction(std::string stdstrFunctionName )
{
for (auto it = this->Functions.begin(); it != this->Functions.end(); ++it)
{
auto& func = *it;
if (func->getFunctionName() == stdstrFunctionName)
return true;
}
return false;
}
my question is that these both are nearly doing the same stuff , is there any difference between the two.
Or just different flavors for the same thing.
Mostly equivalent, but with some differences:
in second snippet func != this->Functions.end(), Functions.end() is called at each loop (might be optimized by compiler with as-if rule, but requires to proof that it is the same).
Depending of standard used (before C++17 or not), type of Functions.end() should be equal to the one from Functions.end() in the for-range variant. So prior to C++17, sentinel end cannot use for range and may use old for loop.
It's mainly the same thing in two flavors. The range-based for loop expands to a loop based on iterators. But note that when the loop is critical for performance, this
for (auto func = this->Functions.begin(); func != this->Functions.end(); ++func)
is not ideal as the compiler might not be able to optimize the query for Functions.end() such that it is invoked only once. Recall that the termination condition in a manual for loop is evaluated every time, you might be better off with
for (auto func = this->Functions.begin(), end = this->Functions.end(); func != end; ++func)
As this necessarily introduces a second variable, it's definitely less readable than the range based for loop, so I'd advice you to use the range based for loop, or, as suggested in the comments, std::any_of from the <algorithm> header.
Having a pair of iterators [begin, end) I want to advance begin while a condition is true and I didn't reach end. As I don't know any "direct" algorithm from the standard library to do this I'm using:
std::find_if_not(begin, end, condition);
but my problem is that the name of the function does't express my intention to advance begin while the condition is true in a clear way.
Is any algorithm in the C++ standard library to advance an iterator while a condition is true?
C++14:
template<class...Args>
auto advance_while_true( Args&&... args ) {
return std::find_if_not( std::forward<Args>(args)... );
}
but really, just use find_if_not. The name might not match your description of the problem, but as a std library algorithm, it is relatively famous.
If the condition is common, write a wrapper that takes two (templetized) iterators and includes the condition inside itself.
template<class Iterator>
std::decay_t<Iterator> advance_while_foo( Iterator first, Iterator last ) {
return std::find_if_not( std::forward<Iterator>(first), std::forward<Iterator>(last),
[](auto&& x) {
return foo(x);
}
);
}
which both uses the std algorithm for the guts (meaning it will be better written than if you write it yourself probably), and gives it a name (foo) that in theory should be appropriate.
(forward and decay_t is probably overkill. Replace auto&& with the stored type const& and std::decay_t<?> with typename std::decay<?>::type if you aren't C++14.)
I think this is most easily expressed by the idiom...
while (condition (begin++));
And if you want to check against an end iterator, just add that to the conditions...
while (begin != end && condition(begin++));
It's a nice little trick (that goes back to C) because it works for things that aren't even technically iterators like...
// Consume leading whitespace
while (isspace(ch = getchar()));
Given...
string a; // = something.
string b; // = something else. The two strings are of equal length.
string::size_type score = 0;
...what I would like to do is something like...
compare(a.cbegin(), a.cend(), b.cbegin(), b.cend(), [&score](const char c1, const char c2) -> void {
if (c1 == c2) { // actually a bit more complicated in real life
score++;
}
});
...but as far as I can tell there doesn't seem to be a std::compare. The nearest seems to be std::lexicographical_compare but that doesn't quite match. Ditto for std::equal. Is there really nothing appropriate in the standard library? I suppose I could write my own (or use a plain old C style loop which is what I did but how boring :-) but I would think what I'm doing is rather common so that would be a strange omission IMO. So my question is am I missing something?
Is there a standard algorithm to compare to ranges using a predicate? Yes, std::equal, or std::lexicographical_compare.
Is there a standard algorithm to do what your code is doing? std::inner_product can be made to do it:
std::string a = "something";
std::string b = "samething";
auto score = std::inner_product(
a.begin(), a.end(), b.begin(), 0,
[](int x, bool b) { return x + b; },
[](char a, char b) { return a == b; });
but I would think what I'm doing is rather common
No, not really. If you just want to run a general function over corresponding elements in two ranges, the appropriate algorithm would be for_each with a zip iterator. If anything's missing from the standard, it's the zip iterator. We don't need a special algorithm for this purpose.
It looks a bit as if you are looking for std::mismatch() which yields the iterators where the first difference is found (or the end, of course). It doesn't compute the difference, however, because there isn't a subtraction defined for all types. Like the other algorithms std::mismatch() comes in a form with a predicate and one without a predicate.
Thankyou to all that answered. What I was trying to do (more for my edification than anything else really) was to replace this...
for (string::const_iterator c1 = a.begin(), c2 = b.begin(); c1 != a.end(); ++c1, ++c2) {
if (*c1 == *c2) {
score++;
}
}
...with snazzy new c++11 stuff :-) I looked at equal, lexicographical_compare etc. but I guess what tripped me up was that they take a boolean predicate and if it returns false processing stops whereas I needed to process the entire ranges each time. Then after reading the answers you gave me I had the epiphany that just because there is a return value doesn't mean I can't throw it away if I don't need it. By simply always returning true in my lambda I can use any of the above mentioned algorithms and they will run to the end of the range.
The only thing is as I would be using the algorithms in a different way than their names suggest, it might cause maintainance problems in the future so I will just stick to my boring old loop for now but I learned something new so thanks once again.
I have defined the following function object:
struct Predicate1
{
__device__ bool operator ()
(const DereferencedIteratorTuple& lhs, const DereferencedIteratorTuple& rhs)
{
using thrust::get;
//if you do <=, returns last occurence of largest element. < returns first
if (get<0>(lhs)== get<2>(lhs) && get<0>(lhs)!= 3) return get<1>(lhs) < get<1>(rhs);
else
return true ;
}
};
where the DereferencedIteratorTuple is as follows:
typedef thrust::tuple<int, float,int> DereferencedIteratorTuple;
Moreover, i call it as follows:
result = thrust::max_element(iter_begin, iter_end, Predicate1());
But the result is the tuple (3,.99,4). I am confused why this is the result because the condition get<0>(lhs)== get<2>(lhs) does not hold in the if for this tuple. Thus, the operator returns true for every comparison of this tuple. However, thrust::max_elementis defined as follows :
"This version compares objects using a function object comp.
Specifically, this version of max_element returns the first iterator i
in [first, last) such that, for every iterator j in [first, last),
comp(*i, *j) is false."
Thus, there is no way this should be chosen as for this tuple, operator never returns false. Please let me know what i am doing wrong
The predicate helps algorithm to determine which element to prefer. If predicate returns true the algorithm prefers rhs over lhs. If it return false the algorithm prefers lhs over rhs. In the case when predicate always returns true the algorithm will select last element in the array. This is true for both stl and thrust algorithms.
I guess, that your result never occured as lhs during comparison process and every time it was not filtered since rhs's second value was smaller than 0.99.
If you want to filter such values you'd better rewrite your predicate.
While using std::for_each algorithm how do I break when a certain condition is satisfied?
You can use std::any_of (or std::all_of or std::none_of) e.g. like this:
std::vector<int> a;
// ...
std::all_of(a.begin(), a.end(), [&](int val) {
// return false if you want to break, true otherwise
});
However, this is a wasteful solution (return values are not really used for anything), and you're better off writing you own loop.
You can use std::find_if algorithm, which will stop and return the iterator to the first element where the predicate condition applied to returns true. So your predicate should be changed to return a boolean as the continue/break condition.
However, this is a hack, so you can use the algorithms.
Another way is to use BOOST_FOREACH.
You can break from the for_each() by throwing an exception from your functor. This is often not a good idea however, and there are alternatives.
You can retain state in your functor. If you detect the 'break' condition, simply set a flag in your functor and then for each subsequent iteration simply return without doing your functor's thing. Obviously this won't stop the iteration, which might be expensive for large collections, but it will at least stop the work from being performed.
If your collection is sorted, you can find() the element that you want to break at, then do for_each from begin() to the element find() returned.
Finally, you can implement a for_each_if(). This will again not stop the iteration but will not evaluate your functor which does the work if the predicate evaluates to false. Here are 2 flavors of for_each_xxx(), one which takes a value and performs the work if operator==() evaluates to true, and another which takes two functors; one which performs a comparison ala find_if(), and the other which performs the work if the comparison operator evaluates to true.
/* ---
For each
25.1.1
template< class InputIterator, class Function, class T>
Function for_each_equal(InputIterator first, InputIterator last, const T& value, Function f)
template< class InputIterator, class Function, class Predicate >
Function for_each_if(InputIterator first, InputIterator last, Predicate pred, Function f)
Requires:
T is of type EqualityComparable (20.1.1)
Effects:
Applies f to each dereferenced iterator i in the range [first, last) where one of the following conditions hold:
1: *i == value
2: pred(*i) != false
Returns:
f
Complexity:
At most last - first applications of f
--- */
template< class InputIterator, class Function, class Predicate >
Function for_each_if(InputIterator first,
InputIterator last,
Predicate pred,
Function f)
{
for( ; first != last; ++first)
{
if( pred(*first) )
f(*first);
}
return f;
};
template< class InputIterator, class Function, class T>
Function for_each_equal(InputIterator first,
InputIterator last,
const T& value,
Function f)
{
for( ; first != last; ++first)
{
if( *first == value )
f(*first);
}
return f;
};
If you want do some actions while condition is not satisfied, maybe you need change algorithm on something like std::find_if?
As already shown by others it is only achievable with workarounds that IMHO obfuscate the code.
So my suggestions is to change the for_each into a regular for loop. This will make it more visible to others that you are using break (and maybe even continue).
You can't do it, unless you throw an exception, which is not a good idea because you don't do flow control with exceptions.
Update: apparently Boost has a for_each_if that might help, but you're not using Boost.
You throw an exception. Whether or not it's a good idea is sort of a style question, pace #Dan, but may be more of an issue with your design. for_each is intended for a sort of functional-programming style, which implicitly assumes that your function can be applied uniformly across the set. So, if you do need to break, that could be consiered an unusual condition, and therefore worthy of an exception.
The other solution, and a more "functional" solution, is to write your function so that if it shouldn't have an effect on some applications, then write it to have no effect. So, for example, if you had a summing function, have it add 0 in the cases you would have "broken" from.
You can use std::find_if instead std::for_each:
int aaa[]{ 1, 2, 3, 4, 5, 6, 7, 8 };
std::find_if(aaa, std::next(aaa, sizeof(aaa) / sizeof(int)), [](const auto &i) {
if (i == 5)
return true;
std::cout << i << std::endl;
return false;
});
Output:
1
2
3
4