std::ranges::empty
来自cppreference.com
在标头 <ranges> 定义
|
||
inline namespace /*unspecified*/ { inline constexpr auto empty = /*unspecified*/; |
(C++20 起) (定制点对象) |
|
调用签名 |
||
template< class T > requires /* see below */ |
||
确定 t
是否拥有任何元素。
令 t
为 T
类型对象。对 ranges::empty
的调用表达式等价于:
- bool(std::forward<T>(t).empty()) ,若该表达式合法。
- 否则为 (ranges::size(std::forward<T>(t)) == 0) ,若该表达式合法。
- 否则为 bool(ranges::begin(t) == ranges::end(t)) 。
所有其他情况下,对 ranges::empty
的调用非良构,这能在 ranges::empty(t) 出现于模板实例化的立即语境中时导致替换失败。
表达式等价
表达式 e 表达式等价于表达式 f ,若 e 与 f 拥有相同效果,均为潜在抛出或均非潜在抛出(即 noexcept(e) == noexcept(f) ),且均为常量子表达式或均非常量子表达式。
定制点对象
名字 ranges::empty
代表一个定制点对象,它是字面 semiregular
类类型的 const 函数对象。为说明目的,以 __empty_fn
表示它的类型的 cv 无限定版本。
__empty_fn
的所有实例均相等。在相同参数上调用类型 __empty_fn
的不同实例的效果是等价的,与指代该实例的表达式是左值还是右值,以及是否为 const 限定无关(然而不要求 volatile 限定的实例可调用)。从而能自由地复制 ranges::empty
并且能彼此替代地使用它的副本。
给定类型集合 Args...
,如果 std::declval<Args>()... 满足上面对于 ranges::empty
的参数要求,那么 __empty_fn
实现
- std::invocable<__empty_fn, Args...>、
- std::invocable<const __empty_fn, Args...>、
- std::invocable<__empty_fn&, Args...> 和
- std::invocable<const __empty_fn&, Args...>。
否则,__empty_fn
的函数调用运算符不会参与重载决议。
示例
运行此代码
#include <iostream> #include <ranges> #include <vector> template <std::ranges::input_range R> void print(R&& r) { if (std::ranges::empty(r)) { std::cout << "\tEmpty\n"; return; } std::cout << "\tElements:"; for (const auto& element : r) { std::cout << ' ' << element; } std::cout << '\n'; } int main() { { auto v = std::vector<int>{1, 2, 3}; std::cout << "1. calling ranges::empty on std::vector:\n"; print(v); v.clear(); print(v); } { std::cout << "2. calling ranges::empty on std::initializer_list:\n"; auto il = {7, 8, 9}; print(il); print(std::initializer_list<int>{}); } { std::cout << "2. calling ranges::empty on a raw array:\n"; int array[] = {4, 5, 6}; // 数组拥有已知边界 print(array); } { struct NoEmptyNorSize : private std::vector<int> { auto begin() { return std::vector<int>::begin(); } auto end() { return std::vector<int>::end(); } }; std::cout << "3. calling ranges::empty on an object that satisfies only case 3):\n"; print(NoEmptyNorSize{}); } }
输出:
1. calling ranges::empty on std::vector: Elements: 1 2 3 Empty 2. calling ranges::empty on std::initializer_list: Elements: 7 8 9 Empty 2. calling ranges::empty on a raw array: Elements: 4 5 6 3. calling ranges::empty on an object that satisfies only case 3): Empty
参阅
(C++17) |
检查容器是否为空 (函数模板) |