我想循环一个向量并过滤掉所有非空指针元素。我正在寻找一个检查某些东西是否为 nullptr 的 std
函数或实际返回传递给它的任何内容的std
函数(如 std::forward
(,因为空指针的计算结果为 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
卡在std
的东西上,你可以将std::remove_copy_if
与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
或者,您可以使用remove_copy
传递nullptr
:
std::remove_copy(dynamicObjects.begin(), dynamicObjects.end(),
std::back_inserter(existingObjects),
nullptr);
如果你真的喜欢copy_if
,你可以在logical_not
上使用not_fn
或not1
。
不。
我确实发现躺着identity
有时很有用:
struct identity_t {
template<class T>
T operator()(T&& t)const{ return std::forward<T>(t); }
constexpr identity_t() {}
};
constexpr identity_t identity;
(它将右值转换为副本,以延长参考寿命(
我主要在编写具有可选映射的函数时使用它,例如转换-过滤器函数:identity
是转换的默认值,always_true
是过滤器的默认值。
标准库中没有这样的东西。从概念上讲,您想要的是:
std::copy_if(dynamicObjects.begin(), dynamicObjects.end(),
std::back_inserter(existingObjects),
bool);
假设您可以将类型名称用作构造该类型实例的工厂函数。但是,这不是你在C++可以做的事情。至少是直接的。我们可以这样写:
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>{});
如果您不喜欢键入 {}
s,可以通过制作变量模板来缩短它。
也就是说,这个问题:
[](const auto a) { return a; } ); // This is awkward
与其说是尴尬,不如说是效率低下——这是两个副本(一个进一个出(。您需要:
[](const auto& a) { return static_cast<bool>(a); }
或者真的只是更早地强制bool
转换:
[](bool b){ return b; }