<ranges>
šablony aliasů
Šablona aliasu je alias pro jiný typ, který může kód lépe čitelný. Například následující alias conditional_t
, je alias pro buď borrowed_range
nebo dangling
rozsah, v závislosti na druhu range
, který je předán:
// requires /std:c++20, or later
#include <iostream>
#include <list>
#include <span>
#include <algorithm>
#include <ranges>
#include <type_traits>
using namespace std;
// Define an alias template called my_iterator_t
// If the provided range R is a borrowed_range, then the
// returned type is iterator_t<R>; otherwise, ranges::dangling
template<ranges::range R>
using my_iterator_t = conditional_t<
ranges::borrowed_range<R>,
ranges::iterator_t<R>, ranges::dangling>;
int main()
{
my_iterator_t<list<int>> aDanglingRange; // list<> isn't a borrowed_range
constexpr bool same = same_as<
decltype(aDanglingRange),
ranges::dangling>; // true
my_iterator_t<span<int, 5>> anIterator_t; // span<> is a borrowed_range
constexpr bool same2 = same_as<
decltype(anIterator_t),
ranges::iterator_t<span<int, 5>>>; // true
cout << boolalpha << same << "," << same2; // outputs true, true
}
Další informace o šablonách aliasů najdete v tématu Aliasy a typedefs.
Hlavička <algorithm>
definuje následující šablony aliasů, které určují typy iterátorů a sentinelů pro :range
Šablona aliasu | Popis |
---|---|
borrowed_iterator_t C++20 |
Zjistěte, jestli iterátor vrácený range pro oblast, jejíž životnost skončila. |
borrowed_subrange_t C++20 |
Určete, jestli vrácená subrange range hodnota odkazuje na oblast, jejíž životnost skončila. |
dangling C++20 |
Označuje, že vrácený iterátor z doby životarange subrange /, na kterou odkazuje.range /subrange |
iterator_t C++20 |
Vrátí typ iterátoru pro zadaný rozsah. |
range_difference_t C++20 |
Vrátí typ rozdílu pro iterátor zadaného rozsahu. |
range_reference_t C++20 |
Vrátí typ odkazu pro iterátor zadaného rozsahu. |
range_rvalue_reference_t C++20 |
Vrátí typ odkazu rvalue pro iterátor zadaného rozsahu. Jinými slovy, typ odkazu rvalue elementů rozsahu. |
range_size_t C++20 |
Vrátí typ použitý k hlášení zadaného rozsahu size . |
range_value_t C++20 |
Vrátí typ hodnoty iterátoru zadané oblasti. Nebo jinými slovy, typ prvků v oblasti. |
sentinel_t C++20 |
Vrátí typ sentinelu pro zadaný rozsah. |
borrowed_iterator_t
Když je volána funkce algoritmu, která vrací iterátor s argumentem rvalue range
, životnost rozsahu může končit voláním. To znamená, že vrácený iterátor může odkazovat na prvky, jejichž životnost skončila. Použití propojeného iterátoru má za následek nedefinované chování.
Tento alias šablony vrátí ranges::dangling
označení, že se jedná o situaci pro daný argument rozsahu nebo std::ranges::iterator_t<R>
že je bezpečné použít vrácený iterátor, protože rozsah, který odkazuje na modely borrowed_range
, nebo se rozsah předal jako lvalue.
template<ranges::range R>
using borrowed_iterator_t = conditional_t<ranges::borrowed_range<R>,
ranges::iterator_t<R>, ranges::dangling>;
Parametry
R
Rozsah, který se má testovat.
Poznámky
Životnost rozsahu rvalue může končit voláním funkce bez ohledu na to, jestli modely borrowed_range
rozsahu nebo ne. Pokud se jedná o borrowed_range
, můžete být schopni dál používat iterátory s dobře definovaným chováním bez ohledu na to, kdy skončí životnost rozsahu.
Případy, kdy to není pravda, jsou například pro kontejnery podobné vector
nebo list
proto, že když skončí životnost kontejneru, iterátory by odkazovaly na prvky, které byly zničeny.
Iterátory můžete dál používat pro view
iota_view<int>{0, 42}
příkladborrowed_range
, jehož iterátory jsou nad sadou hodnot, které nejsou předmětem zničení, protože se generují na vyžádání.
Pokud je funkce algoritmu předána rozsahu, jehož iterátory závisí na jeho životnosti, ranges::dangling
je vrácena místo iterátoru nebo podrange, takže potenciální zneužití se zjistí v době kompilace.
Příklad: borrowed_iterator_t
Následující příklad ukazuje, jak borrowed_iterator_t
detekuje protěžující iterátor. Funkce ranges::max_element()
používá tento alias šablony k určení návratového typu:
// requires /std:c++20, or later
#include <vector>
#include <span>
#include <ranges>
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
// Not dangling ------------------
int a[] = {0,1,2,3};
// not dangling even though an rvalue because span models ranges::borrowed
auto result1 = ranges::max_element(span{a});
cout << boolalpha << ranges::borrowed_range<decltype(span{a})> << endl; // outputs true because the temporary models ranges::borrowed
cout << same_as<decltype(result1), ranges::dangling> << endl; // outputs false because the result isn't dangling
vector<int> v{0,1,2,3}; // doesn't model ranges::borrowed
auto result2 = ranges::max_element(v); // Yet not dangling because passed as an lvalue
cout << same_as<decltype(result2), ranges::dangling> << endl; // outputs false because the result isn't dangling
// Dangling ------------------
auto result3 = ranges::max_element(vector{0,1,2,3}); // dangling because vector doesn't model ranges::borrowed and is passed as an rvalue
cout << same_as<decltype(result3), ranges::dangling>; // outputs true because the result is dangling
}
true
false
false
true
borrowed_subrange_t
Pokud je volána funkce algoritmu, která vrací subrange
argument rvalue range
, životnost rozsahu může končit voláním. To znamená, že vrácený subrange
prvek by mohl odkazovat na prvky, jejichž životnost skončila. Použití přeskakujícího subrange
výsledku způsobí nedefinované chování.
Tento alias šablony buď vrátí ranges::dangling
označení, že to může být situace pro daný argument rozsahu, nebo subrange<ranges::iterator_t<R>>
pro označení, že je bezpečné použít vrácené dílčí uspořádání, protože oblast, jejíž prvky odkazuje na modely borrowed_range
, nebo se oblast předala jako lvalue.
template<ranges::range R>
using borrowed_subrange_t = conditional_t<ranges::borrowed_range<R>,
ranges::subrange<ranges::iterator_t<R>>, ranges::dangling>;
Parametry
R
Rozsah, který se má testovat.
Poznámky
Životnost rozsahu rvalue může končit voláním funkce bez ohledu na to, jestli modely borrowed_range
rozsahu nebo ne. Pokud se jedná o borrowed_range
, můžete být schopni dál používat iterátory s dobře definovaným chováním bez ohledu na to, kdy skončí životnost rozsahu.
Případy, kdy to není pravda, jsou například pro kontejnery podobné vector
nebo list
proto, že když skončí životnost kontejneru, iterátory by odkazovaly na prvky, které byly zničeny.
Iterátory můžete dál používat pro view
iota_view<int>{0, 42}
příkladborrowed_range
, jehož iterátory jsou nad sadou hodnot, které nejsou předmětem zničení, protože se generují na vyžádání.
Pokud je funkce algoritmu předána rozsahu, jehož iterátory závisí na jeho životnosti, vrátí se místo poduskupování, ranges::dangling
aby se v době kompilace zjistilo možné zneužití.
Příklad: borrowed_subrange_t
Následující příklad ukazuje, jak borrowed_subrange_t
zjistí dangling iterator, protože equal_range()
a max_element
použít tento alias šablony k určení návratového typu:
// requires /std:c++20, or later
#include <vector>
#include <iostream>
#include <algorithm>
#include <span>
#include <ranges>
int main()
{
using namespace std;
// Not dangling ------------------
vector vec{0, 1, 1, 2};
auto result1 = ranges::equal_range(span{vec}, 1); // not dangling even though passing as an rvalue because span models borrowed_range
cout << boolalpha << ranges::borrowed_range<decltype(span{vec})> << endl; // true because the temporary is a borrowed range
cout << boolalpha << same_as<decltype(result1), ranges::dangling> << endl; // false because the result isn't dangling
// result2 isn't dangling even though vec doesn't model ranges::borrowed because it's an lvalue
auto result2 = ranges::max_element(vec);
cout << boolalpha << ranges::borrowed_range<decltype(vec)> << endl; // false because vector isn't a borrowed_range
cout << boolalpha << same_as<decltype(result2), ranges::dangling> << endl; // false because the result isn't dangling
// Dangling -----------------------
// result3 is dangling because the temporary is an rvalue that doesn't model borrowed_range
auto result3 = ranges::max_element(vector{0,1,1,2});
cout << boolalpha << same_as<decltype(result3), ranges::dangling> << endl; // true because the result is dangling
}
true
false
false
false
true
dangling
Pokud je volána funkce algoritmu, která vrací iterátor nebo je subrange
volána s argumentem rvalue range
, životnost argumentu rozsahu může končit po volání. To znamená, že vrácený iterátor nebo subrange
by mohl odkazovat na prvky, jejichž životnost skončila. Použití přeskakujícího iterátoru nebo subrange
má za následek nedefinované chování.
Pokud je funkce algoritmu předána rozsahu, jehož iterátory závisí na jeho životnosti, vrátí se místo iterátoru nebo dílčího uspořádání, ranges::dangling
aby se potenciální zneužití zjistilo v době kompilace.
1) constexpr dangling() noexcept = default;
2) template<class... Args>
constexpr dangling(Args&&...) noexcept {}
Parametry
Args
Proměnný počet netypůvoid
. Nemají žádný vliv. Argumenty jsou pohodlí, takže k vytvoření typu dangling
iterátoru a typu nepotřebujete různé cesty kódu. To je užitečné, když předaná hodnota označuje, že dangling
se má vrátit místo iterátoru.
Příklad: dangling
Následující příklad ukazuje, jak max_element
detekuje protěžující iterátor.
// requires /std:c++20, or later
#include <vector>
#include <iostream>
#include <ranges>
#include <algorithm>
using namespace std;
int main()
{
auto result1 = ranges::max_element(vector{1,2,3}); // dangling because vector doesn't model ranges::borrowed and is passed as an rvalue
cout << boolalpha << same_as<decltype(result1), ranges::dangling> << endl; // outputs true because the result is dangling
vector<int> v{3,4,5};
auto result2 = ranges::max_element(v); // Not dangling because passed as an lvalue
cout << same_as<decltype(result2), ranges::dangling>; // outputs false because the result isn't dangling
}
true
false
iterator_t
Tento alias šablony vrátí typ iterátoru, který se používá k iteraci zadaného typu rozsahu.
template<class T>
using iterator_t = decltype(ranges::begin(declval<T&>()));
Parametry
T
Typ rozsahu, pro který chcete získat typ iterátoru.
Příklad: iterator_t
Následující příklad ukazuje, jak iterator_t
lze použít k deklaraci iterátoru pro vektor:
// requires /std:c++20, or later
#include <vector>
#include <ranges>
#include <iostream>
int main()
{
using namespace std;
vector<int> v{1,2,3};
ranges::iterator_t<decltype(v)> it = v.begin();
cout << *it << "\n"; // outputs 1
cout << typeid(it).name(); // outputs class _Vector_iterator<class _Vector_val<struct _Simple_types<int>>>
}
1
class std::_Vector_iterator<class std::_Vector_val<struct std::_Simple_types<int> > >
range_difference_t
Vrátí typ rozdílu pro iterátor zadaného rozsahu.
template<range R>
using range_difference_t = iter_difference_t<iterator_t<R>>;
Parametry
R
Rozsah, jehož iterátor poskytne typ rozdílu.
Příklad: range_difference_t
Následující příklad ukazuje, jak range_difference_t
se používá k uložení vzdálenosti mezi prvky v oblasti:
// requires /std:c++20, or later
#include <vector>
#include <ranges>
#include <iostream>
int main()
{
using namespace std;
vector<int> v{1,2,3};
auto findIt = ranges::find(v, 2);
// type of distance is ptrdiff_t
ranges::range_difference_t<decltype(v)> distance = ranges::distance(v.begin(), findIt);
cout << distance << endl; // outputs 1
}
1
range_reference_t
Vrátí typ odkazu pro iterátor zadaného rozsahu. Jinými slovy, typ odkazu prvků oblasti.
template <range R>
using range_reference_t = iter_reference_t<ranges::iterator_t<R>>;
Parametry
R
Oblast, pro kterou je vrácen typ odkazu jeho iterátoru.
Příklad: range_reference_t
Následující příklad ukazuje range_reference_t
odkaz na typ prvků v oblasti:
// requires /std:c++20, or later
#include <vector>
#include <ranges>
#include <iostream>
int main()
{
using namespace std;
vector<int> v{1,2,3};
ranges::range_reference_t<decltype(v)> ref = v[0];
cout << ref << endl; // outputs 1
cout << typeid(ref).name() << endl; // outputs int
}
1
int
range_rvalue_reference_t
Vrátí typ odkazu rvalue pro iterátor zadaného rozsahu. Jinými slovy, typ odkazu rvalue elementů rozsahu.
template <range R>
using range_rvalue_reference_t = iter_reference_t<ranges::iterator_t<R>>;
Parametry
R
Rozsah, který získá typ odkazu rvalue na typ iterátoru.
Příklad: range_rvalue_reference_t
Následující příklad ukazuje range_rvalue_reference_t
odkaz na typ rvalue prvků v rozsahu:
// requires /std:c++20, or later
#include <vector>
#include <ranges>
#include <iostream>
int main()
{
using namespace std;
vector<int> v{1,2,3};
ranges::range_rvalue_reference_t<decltype(v)> elementRvalueType = v[0] * 10; // elementRvalueType is int&&
cout << elementRvalueType << endl; // outputs 10
cout << typeid(elementRvalueType).name() << endl; // outputs int
}
10
int
range_size_t
Vrátí typ size
funkce pro zadanou sized_range
hodnotu .
template <range R>
using range_size_t = iter_reference_t<ranges::iterator_t<R>>;
Parametry
R
Oblast pro získání typu funkce size
.
Příklad: range_size_t
Následující příklad ukazuje range_size_t
odkaz na počet prvků v oblasti:
// requires /std:c++20, or later
#include <vector>
#include <iostream>
#include <ranges>
int main()
{
using namespace std;
vector<int> v{1,2,3};
ranges::range_size_t<decltype(v)> size = v.size();
cout << size << endl; // outputs 3
cout << typeid(size).name(); // outputs unsigned __int64
}
3
unsigned __int64
range_value_t
Vrátí typ hodnoty iterátoru zadané oblasti. Nebo jinými slovy, typ prvků v oblasti.
template <ranges::range R>
using range_value_t = iter_value_t<ranges::iterator_t<R>>;
Parametry
R
Oblast pro získání typu hodnoty iterátoru.
Příklad: range_value_t
Následující příklad ukazuje, jak range_value_t
odkazuje na typ prvků v oblasti:
// requires /std:c++20, or later
#include <vector>
#include <ranges>
#include <iostream>
int main()
{
using namespace std;
vector<int> v{1,2,3};
ranges::range_value_t<decltype(v)> elementType = v[2]; // elementType is an int
cout << elementType << endl; // outputs 3
cout << typeid(elementType).name() << endl; // outputs int
}
3
unsigned int
sentinel_t
Vrátí typ sentinelu pro zadaný rozsah.
template <range R>
using sentinel_t = decltype(ranges::end(declval<R&>()));
Parametry
R
Rozsah, pro který se má získat typ sentinelu.
Příklad: sentinel_t
Následující příklad ukazuje použití sentinel_t
k určení, jestli je typ iterátoru a typ sentinelu stejný:
// requires /std:c++20, or later
#include <iostream>
#include <list>
#include <ranges>
int main()
{
using namespace std;
list myList{1, 2, 3};
ranges::subrange count = std::views::counted(myList.begin(), myList.size());
ranges::iterator_t<decltype(count)> first;
ranges::sentinel_t<decltype(count)> last;
// The iterator type and the sentinel type of a subrange
// obtained from views::counted are not the same
cout << boolalpha << is_same<decltype(first), decltype(last)>::value << endl; // outputs false
cout << "iter: " << typeid(first).name() << "\n\n end: " << typeid(last).name() << endl;
}
false
iter: class std::counted_iterator<class std::_List_iterator<class std::_List_val<struct std::_List_simple_types<int> > > >
end: struct std::default_sentinel_t