The function returns its argument or checks for nullptr
I would like to loop over a vector and filter out all elements with a non-null pointer. I'm looking for a function std
that checks that something is a nullptr function or std
that actually returns whatever is passed to it (for example std::forward
), since a null pointer will evaluate to a value false
.
std::copy_if(dynamicObjects.begin(), dynamicObjects.end(),
std::back_inserter(existingObjects),
std::is_pointer<ObjectType*>); // This does not compile
std::copy_if(dynamicObjects.begin(), dynamicObjects.end(),
std::back_inserter(existingObjects),
std::forward<ObjectType*>); // This does not compile either
std::copy_if(dynamicObjects.begin(), dynamicObjects.end(),
std::back_inserter(existingObjects),
static_cast<bool>); // This won't help me :)
std::copy_if(dynamicObjects.begin(), dynamicObjects.end(),
std::back_inserter(existingObjects),
[] (const auto a) { return a; } ); // This is awkward
source to share
Pinned file in std
, you can use std::remove_copy_if
with std::logical_not
.
std::remove_copy_if(dynamicObjects.begin(), dynamicObjects.end(),
std::back_inserter(existingObjects),
std::logical_not<ObjectType*>()); // or std::logical_not<> in C++14
Or you can use remove_copy
transfer nullptr
:
std::remove_copy(dynamicObjects.begin(), dynamicObjects.end(),
std::back_inserter(existingObjects),
nullptr);
If you really like copy_if
, you can use not_fn
or not1
instead logical_not
.
source to share
Nope.
I find what identity
lies around to be useful sometimes:
struct identity_t {
template<class T>
T operator()(T&& t)const{ return std::forward<T>(t); }
constexpr identity_t() {}
};
constexpr identity_t identity;
(it converts rvalues ββto copies, for a reference lifespan extension)
I mainly use it when writing functions with optional mappings, such as the filter function of filters: identity
is the default for the transformation, and always_true
is the default filter.
source to share
There is nothing like this in the standard library. Conceptually what you need:
std::copy_if(dynamicObjects.begin(), dynamicObjects.end(),
std::back_inserter(existingObjects),
bool);
assuming you can use type names as factory functions that construct instances of that type. But this is not something you can do in C ++. At least directly. We can write that:
template <class T>
struct factory {
template <class... Args>
T operator()(Args&&... args) const {
return T(std::forward<Args>(args)...);
}
};
std::copy_if(dynamicObjects.begin(), dynamicObjects.end(),
std::back_inserter(existingObjects),
factory<bool>{});
If you don't like typing {}
s, you can shorten that by making a variable template.
However, the problem with this:
[](const auto a) { return a; } ); // This is awkward
- it's not so much that it is inconvenient, how inefficient it is - that there are two copies (one in one, one). You need:
[](const auto& a) { return static_cast<bool>(a); }
Or actually just force the conversion bool
before:
[](bool b){ return b; }
source to share