我有这个代码:
for (auto e : foo | ::std::views::take_while([](const char* x) { return x != nullptr; }))
std::cout << e << "\n";
Run Code Online (Sandbox Code Playgroud)
一切都很好,很花哨,但是这个 lambda 很长很笨拙。由于它发生了很多次,我决定用一个命名的函数对象来代替。
class non_null
{
template <typename T> bool operator()(const T* t) {
return t != nullptr;
}
};
for (auto e : foo | ::std::views::take_while(non_null()))
std::cout << e << "\n";
Run Code Online (Sandbox Code Playgroud)
这无法通过大量错误消息进行编译,顶部有“类模板参数推导失败”。
为什么?可以做些什么呢?(除了take_while使用非模板化谓词调用,这显然有效)。
std::views::take_while 需要传递给它的对象的调用运算符是 const 限定的,以便推导成功:
struct non_null
{
template <typename T>
bool operator()(const T* t) const { // <-- const-qualified
return t != nullptr;
}
};
Run Code Online (Sandbox Code Playgroud)
但是,如果您只想命名谓词,您可以简单地执行以下操作:
auto non_null = [](const auto* x) { return x != nullptr; };
Run Code Online (Sandbox Code Playgroud)
并像这样使用它:
for (auto e : foo | ::std::views::take_while(non_null))
std::cout << e << "\n";
Run Code Online (Sandbox Code Playgroud)
这是一个演示。