我有一个std::vector<std::vector<int>>
,我想检查是否至少有一个子向量是空的。所以我有这个:
std::any_of(vec.begin(), vec.end(), [](const auto& subvec) {
return subvec.empty();
});
字符串
C++14中有这样的东西吗?
std::any_of(vec.begin(), vec.end(), std::vector<int>::empty);
型
我尝试了上面的语法,但不起作用,在方法前面加上一个&
也不起作用。
3条答案
按热度按时间c8ib6hqw1#
在评论中,你说:
没有什么不好的,除了如果确实有一个更短和(可以说)更可读的方式来写它,
所以你真正想要的是使用命名函数(一个很好的编程实践)。我们可以这样做,仍然使用lambda。只需创建一个命名lambda。
字符串
hrysbysz2#
使用lambda是可读的方式。
仅用于说明,让我们探索其他方法。 predicate
p
需要(从cppreference):对于
v
类型的每个参数,表达式p(v)
必须可转换为bool
(可能是const)VT
,其中VT
是InputIt
的值类型,无论值类别如何,都不能修改v
。因此,不允许VT&
的参数类型,VT
也不是,除非对于VT
,移动等价于复制(C++11起)。除了隐式转换之外,这基本上意味着 predicate 必须是具有签名
bool (const std::vector<int>&)
的可调用。std::function
是一个候选者。它带来了相当大的开销,因为它的主要目的是类型擦除。我们不需要类型擦除,但std::function
也有一种机制,可以将成员函数指针转换为可调用对象,其中对象被传递给函数。即,我们可以将&std::vector<int>::empty
,一个成员函数指针,转换为带有签名bool (const std::vector<int>&)
的东西。到目前为止一切顺利,但是这种转换不是隐式的,并且不能很好地与类模板参数演绎一起使用。因此,语法相当笨拙:字符串
Live Demo的
嗯.我们可以把成员函数指针变成一个带有右签名的可调用对象,但是
std::function
并不是这里真正需要的,它对简洁的语法没有帮助。写一个自定义的 Package 器怎么样:型
这导致调用的语法很好。直接传递成员函数是不可能的,但这是最接近的。然而,
class_type
在这里有点欺骗。你需要更多的专门化来覆盖所有的const
/ non-const,而不是noexcept
等变体。当成员函数被重载时,情况会变得更糟。这不是你真正想写的东西。Live Demo的
结论:lambda表达式是 Package 成员函数的轻量级、易读的方法。我怀疑它能变得更易读。
3hvapo4f3#
问题是C++中灵活的重载规则和缺乏重载集管理的语义。成员函数可以通过CV以及其对象的引用(右值/左值)限定来重载:
字符串
现在表达式
&foo::bar
变得模糊了:有一个重载带有const左值对象,还有一个重载带有右值可变对象。消除表达式模糊的唯一方法是:1.显式转换:
型
1.或者绑定到调用站点的对象,它只能被 Package 为lambda。
但是如果函数没有重载,可以通过获取其地址来创建函数指针:
&foo::bz
工作没有任何问题。为了解决上述问题,由Eric Neibler开创的
<ranges>
库引入了Neibloid模式。这个想法可以在任何非成员函数中实现。上面的链接中提供的文章并不是直接回答你的问题。但它是由C++社区的一个超级活跃的成员撰写的,向你展示了这种语言面临的许多挑战和技术细节。