返回其参数或检查 nullptr 的函数
Function returning its argument or checking for nullptr
我想循环一个向量并过滤掉所有非空指针元素。我正在寻找一个 std
函数来检查是否为 nullptr 或 std
函数实际上 returns 传递给它的任何东西(比如 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
没有。
我确实发现 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; }
坚持使用 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
。
我想循环一个向量并过滤掉所有非空指针元素。我正在寻找一个 std
函数来检查是否为 nullptr 或 std
函数实际上 returns 传递给它的任何东西(比如 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
没有。
我确实发现 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; }
坚持使用 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
。