Reputation: 2898
I had hoped for a short, concise, elegant:
std::array<int*,10> ip_arr;
bool all_null = std::all_of(ip_arr.begin(),ip_arr.end(),std::is_null_ptr_as_fn);
instead of inventing a lambda for that purpose:
std::array<int*,10> ip_arr;
bool all_null = std::all_of(ip_arr.begin(),ip_arr.end(),[](int *ip){ return ip == nullptr;});
which may even be suspicious because I ignored std::is_null_ptr
and instead it should read like:
std::array<int*,10> ip_arr;
bool all_null = std::all_of(ip_arr.begin(),ip_arr.end(),[](int *ip){ std::is_null_ptr r(ip); return r();});
Yuck.
Upvotes: 2
Views: 445
Reputation: 123440
There is no std::is_null_ptr
. In case you refer to std::is_null_pointer
, its a type trait to check if some type is nullptr_t
. You have an array of int*
there is no nullptr_t
anywhere, the trait is of no help here.
Your version with the lambda is ok. Thats what lambdas were invented for. Do not expect to find functions for everything in the standard library.
PS: Also your request for a std::function
is a little misguided. std::function
is what you need for type erased callables. For example you want to store pointer to free function, an instance of a lambda, or others in the same variable, then you use a std::function
. If you do not need type erasure, then you do not need std::function
. std::function
is not the type to be used whenever you pass functions around. Admittedly its name can be a bit confusing.
Upvotes: 4
Reputation: 10007
You can use std::indentity
from C++20. As pointers can be implicitly converted to bool,
std::all_of(ip_arr.begin(), ip_arr.end(), std::identity());
will test if all pointers are not nullptrs.
To test if all pointers are null (as you are asking), you can use any_of
and negate the result:
not std::any_of(ip_arr.begin(), ip_arr.end(), std::identity());
of invert the std::indentity
result:
std::all_of(ip_arr.begin(), ip_arr.end(), std::not_fn(std::identity()));
Although your code with lambda may be more readable and easier to understand.
Upvotes: 7
Reputation:
The standard library provides several function objects for arithmetic and logical operations: https://en.cppreference.com/w/cpp/utility/functional
You can use logical_not
to detect pointer null-ness.
bool all_null = std::all_of(ip_arr.begin(), ip_arr.end(), std::logical_not{});
Note that we're passing an instance of the function object (using {}
or ()
to instance it).
As indicated by other answers and comments however, the lambda in your second code snippet might be considered more readable, with clearer intent, without relying on implicit pointer-to-bool conversion.
If you're seeking conciseness for this, or any other lambda predicate, you could name it for re-use:
auto is_null = [](auto *t) { return t == nullptr; };
bool all_null = std::all_of(ip_arr.begin(), ip_arr.end(), is_null);
or composition with other function objects:
bool all_null = std::none_of(ip_arr.begin(), ip_arr.end(), std::not_fn(is_null));
Upvotes: 1