std::ranges::empty
| Definido en el archivo de encabezado <ranges>
|
||
inline namespace /*sin especificar*/ { inline constexpr auto empty = /*sin especificar*/; } |
(desde C++20) (objeto punto de personalización) |
|
| Call signature |
||
template< class T > requires /* véase más abajo */ constexpr bool empty(T&& t); |
||
Determina si t tiene o no elementos.
Dejemos que t sea un objeto de tipo T. Una llamada a ranges::empty es equivalente-en-expresión a:
bool(std::forward<T>(t).empty()), si esa expresión es válida.- De lo contrario,
(ranges::size(std::forward<T>(t)) == 0), si esa expresión es válida. - De lo contrario,
bool(ranges::begin(t) == ranges::end(t))
En todos los demás casos, una llamada a ranges::empty está mal formada, que puede resultar en falla en la sustitución cuando ranges::empty(t) aparece en el contexto inmediato de una instanciación de una plantilla.
Equivalente en expresión
La expresión e es equivalente-en-expresión a la expresión f, si e y f tienen los mismos efectos, ambas potencialmente lanzan o ambas potencialmente no lanzan (es decir, noexcept (e) == noexcept(f)), y ambas son subexpresiones constantes o ambas no son subexpresiones constantes.
Objetos de punto de personalización
El nombre ranges::empty denota un objeto de punto de personalización, que es un objeto función const de un tipo clase literal semiregular (denotado, a efectos de exposición, como empty_ftor). Todos los ejemplares de empty_ftor son iguales. Por lo tanto, ranges::empty puede copiarse libremente y sus copias pueden usarse indistintamente.
Dado un conjunto de tipos Args..., si std::declval<Args>()... cumple con los requerimientos para los argumentos de ranges::empty mencionado anteriormente, empty_ftor satisfará a std::invocable<const empty_ftor&, Args...>. De lo contrario, ningún operador de llamada a función de empty_ftor participa en la resolución de sobrecarga.
Ejemplo
#include <iostream>
#include <ranges>
#include <vector>
template <std::ranges::input_range R>
void print(R&& r)
{
if (std::ranges::empty(r)) {
std::cout << "\Vacio\n";
return;
}
std::cout << "\tElementos:";
for (const auto& element : r) {
std::cout << ' ' << element;
}
std::cout << '\n';
}
int main()
{
{
auto v = std::vector<int>{1, 2, 3};
std::cout << "1. llamando a ranges::empty en std::vector:\n";
print(v);
v.clear();
print(v);
}
{
std::cout << "2. llamando a ranges::empty en std::initializer_list:\n";
auto il = {7, 8, 9};
print(il);
print(std::initializer_list<int>{});
}
{
std::cout << "2. llamando a ranges::empty en un array sin formato:\n";
int array[] = {4, 5, 6}; // array has a known bound
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. llamando a ranges::empty en un objeto que satisface solo el caso 3):\n";
print(NoEmptyNorSize{});
}
}
Salida:
1. llamando a ranges::empty en std::vector:
Elementos: 1 2 3
Vacio
2. llamando a ranges::empty en std::initializer_list:
Elementos: 7 8 9
Vacio
2. llamando a ranges::empty en un array sin formato:
Elementos: 4 5 6
3. llamando a ranges::empty que satisface solo el caso 3):
Vacio
Véase también
(C++17) |
Comprueba si un contenedor está vacío (plantilla de función) |