Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
Kavramlar, derleme zamanında şablon parametrelerini kısıtlayan bir C++20 dil özelliğidir. Yanlış şablon örneğini önlemeye, şablon bağımsız değişken gereksinimlerini okunabilir bir biçimde belirtmeye ve şablonla ilgili daha kısa derleyici hataları sağlamaya yardımcı olur.
Bölmeyi desteklemeyen bir türe sahip bir şablonun örneğini oluşturmayı önlemek için bir kavram tanımlayan aşağıdaki örneği göz önünde bulundurun:
// requires /std:c++20 or later
#include <iostream>
// Definition of dividable concept which requires
// that arguments a & b of type T support division
template <typename T>
concept dividable = requires (T a, T b)
{
a / b;
};
// Apply the concept to a template.
// The template will only be instantiated if argument T supports division.
// This prevents the template from being instantiated with types that don't support division.
// This could have been applied to the parameter of a template function, but because
// most of the concepts in the <ranges> library are applied to classes, this form is demonstrated.
template <class T> requires dividable<T>
class DivideEmUp
{
public:
T Divide(T x, T y)
{
return x / y;
}
};
int main()
{
DivideEmUp<int> dividerOfInts;
std::cout << dividerOfInts.Divide(6, 3); // outputs 2
// The following line will not compile because the template can't be instantiated
// with char* because char* can't be divided
DivideEmUp<char*> dividerOfCharPtrs; // compiler error: cannot deduce template arguments
}
Derleyici anahtarını /diagnostics:caret Visual Studio 2022 sürüm 17.4 önizleme 4 veya sonraki bir sürüme geçirdiğinizde, false olarak değerlendirilen kavram dividable<char*> hatası doğrudan başarısız olan ifade gereksinimine (a / b) işaret eder.
Aralık kavramları ad alanında std::ranges tanımlanır ve üst bilgi dosyasında bildirilir <ranges> . Bunlar, aralık bağdaştırıcılarının, görünümlerin vb. bildirimlerinde kullanılır.
Altı aralık kategorisi vardır. Bunlar, kavramlarda <iterator>listelenen yineleyici kategorileri ile ilgilidir. Kapasiteyi artırmak için kategoriler şunlardır:
| Aralık kavramı | Açıklama |
|---|---|
output_rangeinput_range |
Yazabileceğiniz bir aralığı belirtir. Bir kereden okuyabileceğiniz bir aralık belirtir. |
forward_range |
Birden çok kez okuyabileceğiniz (ve muhtemelen yazabileceğiniz) bir aralık belirtir. |
bidirectional_range |
Hem ileri hem de geri okuyabileceğiniz ve yazabileceğiniz bir aralık belirtir. |
random_access_range |
Dizine göre okuyabileceğiniz ve yazabileceğiniz bir aralık belirtir. |
contiguous_range |
Öğeleri bellekte sıralı olan, aynı boyutta olan ve işaretçi aritmetiği kullanılarak erişilebilen bir aralığı belirtir. |
Yukarıdaki tabloda kavramlar, özelliği artırma sırasına göre listelenmiştir. Bir kavramın gereksinimlerini karşılayan bir aralık genellikle kendisinden önceki satırlardaki kavramların gereksinimlerini karşılar. Örneğin, , random_access_range , bidirectional_rangeforward_rangeve input_rangeözelliğine output_rangesahiptir. Özel durum , input_rangeiçin yazılamaz, bu nedenle özelliklerine output_rangesahip değildir.
Diğer aralık kavramları şunlardır:
| Aralık kavramı | Açıklama |
|---|---|
range
C++20 |
Yineleyici ve sentinel sağlayan bir tür belirtir. |
borrowed_range
C++20 |
Aralığın yineleyicilerinin ömrünün aralığın ömrüne bağlı olmadığını belirtir. |
common_range
C++20 |
Aralığın yineleyici türünün ve aralığın sentinel türünün aynı olduğunu belirtir. |
Simple_View
C++20 |
Standart kitaplığın bir parçası olarak tanımlanan resmi bir kavram değildir, ancak bazı arabirimlerde yardımcı kavram olarak kullanılır. |
sized_range
C++20 |
Öğe sayısını verimli bir şekilde sağlayabilecek bir aralık belirtir. |
view
C++20 |
Verimli (sabit süre) taşıma yapısı, ataması ve imhası olan bir tür belirtir. |
viewable_range
C++20 |
Görünüm olan veya bir görünüme dönüştürülebilecek bir tür belirtir. |
bidirectional_range
A bidirectional_range , aralığı ileri ve geri okumayı ve yazmayı destekler.
template<class T>
concept bidirectional_range =
forward_range<T> && bidirectional_iterator<iterator_t<T>>;
Parametreler
T
Olup olmadığını bidirectional_rangegörmek için test etmek için gereken tür.
Açıklamalar
Bu tür aralıklar veya üzerini destekler bidirectional_iterator .
A bidirectional_iterator , 'nin özelliklerine forward_iteratorsahiptir, ancak geriye doğru da yineleyebilir.
bazı örnek olarak bidirectional_rangestd::set, std::vectorve std::listverilebilir.
borrowed_range
Nesneden edindiğiniz yineleyicilerin geçerliliği nesnenin ömründen uzun süre dayanabiliyorsa tür modelleri borrowed_range . Başka bir ifadeyle, bir aralığın yineleyicileri, aralık artık mevcut olmasa bile kullanılabilir.
template<class T>
concept borrowed_range =
range<T> &&
(is_lvalue_reference_v<T> || enable_borrowed_range<remove_cvref_t<T>>);
Parametreler
T
Olup olmadığını borrowed_rangegörmek için test etmek için gereken tür.
Açıklamalar
Bir rvalue aralığının ömrü, aralık modellerine borrowed_range bakılmaksızın bir işlev çağrısının ardından sona erebilir. Bu bir borrowed_rangeise, aralığın ömrü sona erdiğinde bağımsız olarak iyi tanımlanmış davranışlarla yineleyicileri kullanmaya devam edebilirsiniz.
Bunun doğru olmadığı durumlar, örneğin veya vector gibi list kapsayıcılar için geçerlidir çünkü kapsayıcının ömrü sona erdiğinde yineleyiciler yok edilmiş öğelere başvurur.
Yineleyicileri, örneğin yineleyicileri isteğe bağlı olarak oluşturulduğu için borrowed_rangeyok edilmeye tabi olmayan değerler kümesi üzerinde olan değerler viewiota_view<int>{0, 42} gibi bir için kullanmaya devam edebilirsiniz.
common_range
için yineleyici common_range türü, sentinel türüyle aynıdır. Başka bir ifadeyle begin()end() aynı türü döndürür.
template<class T>
concept common_range =
ranges::range<T> && std::same_as<ranges::iterator_t<T>, ranges::sentinel_t<T>>;
Parametreler
T
Olup olmadığını common_rangegörmek için test etmek için gereken tür.
Açıklamalar
ve türünden std::ranges::begin()std::ranges::end() almak, iki yineleyici arasındaki uzaklığı hesaplayan algoritmalar ve yineleyici çiftleri tarafından belirtilen aralıkları kabul eden algoritmalar için önemlidir.
Standart kapsayıcılar (örneğin, vector) gereksinimlerini common_rangekarşılar.
contiguous_range
öğesinin contiguous_range öğeleri bellekte sıralı olarak depolanır ve işaretçi aritmetiği kullanılarak erişilebilir. Örneğin, dizi bir contiguous_range'dir.
template<class T>
concept contiguous_range =
random_access_range<T> && contiguous_iterator<iterator_t<T>> &&
requires(T& t) {{ ranges::data(t) } -> same_as<add_pointer_t<range_reference_t<T>>>;};
Parametreler
T
Olup olmadığını contiguous_rangegörmek için test etmek için gereken tür.
Açıklamalar
contiguous_range öğeleri bellekte sıralı olarak yerleştirildiğinden ve aynı boyutta olduğundan, öğesine işaretçi aritmetiği tarafından erişilebilir. Bu tür bir aralık, tüm yineleyiciler arasında en esnek olan öğesini destekler contiguous_iterator.
bazı örnek olarak contiguous_rangestd::array, std::vectorve std::stringverilebilir.
Örnek: contiguous_range
Aşağıdaki örnekte, bir erişim için işaretçi aritmetiği kullanımı gösterilmektedir contiguous_range:
// requires /std:c++20 or later
#include <ranges>
#include <iostream>
#include <vector>
int main()
{
// Show that vector is a contiguous_range
std::vector<int> v = {0,1,2,3,4,5};
std::cout << std::boolalpha << std::ranges::contiguous_range<decltype(v)> << '\n'; // outputs true
// Show that pointer arithmetic can be used to access the elements of a contiguous_range
auto ptr = v.data();
ptr += 2;
std::cout << *ptr << '\n'; // outputs 2
}
true
2
forward_range
A forward_range , aralığı birden çok kez okumayı (ve yazmayı) destekler.
template<class T>
concept forward_range = input_range<T> && forward_iterator<iterator_t<T>>;
Parametreler
T
Olup olmadığını forward_rangegörmek için test etmek için gereken tür.
Açıklamalar
Bu tür aralıklar veya üzerini destekler forward_iterator . Bir forward_iterator , bir aralığı birden çok kez yineleyebilir.
input_range
, input_range bir kereden okunabilen bir aralıktır.
template<class T>
concept input_range = range<T> && input_iterator<iterator_t<T>>;
Parametreler
T
Olup olmadığını input_rangegörmek için test etmek için türü.
Açıklamalar
Bir tür gereksinimlerini input_rangekarşıladığında:
-
ranges::begin()işlevi birinput_iteratordöndürür. Birbegin()üzerinde birden çok kez çağrılmasıinput_rangetanımsız davranışla sonuçlanır. - Her seferinde aynı değeri veren bir başvuruyu art arda kaldırabilirsiniz
input_iterator. Birinput_range, çoklu geçiş değildir. Yineleyicinin artırılması tüm kopyaları geçersiz kılır. - ile
ranges::for_eachkullanılabilir. - Veya üstünü destekler
input_iterator.
output_range
, output_range yazabileceğiniz bir aralıktır.
template<class R, class T>
concept output_range = range<R> && output_iterator<iterator_t<R>, T>;
Parametreler
R
Aralığın türü.
T
Aralığa yazacak verilerin türü.
Açıklamalar
bunun anlamı output_iterator<iterator_t<R>, T> , türünün türündeki değerleri bir tür T aralığına yazabilen bir yineleyici sağlamasıdır R. Başka bir deyişle, veya üstünü destekler output_iterator .
random_access_range
, random_access_range bir aralığı dizine göre okuyabilir veya yazabilir.
template<class T>
concept random_access_range =
bidirectional_range<T> && random_access_iterator<iterator_t<T>>;
Parametreler
T
Olup olmadığını random_access_rangegörmek için test etmek için gereken tür.
Açıklamalar
Bu tür aralıklar veya üzerini destekler random_access_iterator . , random_access_range , input_rangeoutput_rangeve forward_rangeözelliklerine bidirectional_rangesahiptir. A random_access_range sıralanabilir.
bazı örnek olarak random_access_rangestd::vector, std::arrayve std::dequeverilebilir.
range
Bir türün olması için rangekarşılaması gereken gereksinimleri tanımlar. A range , öğeleri üzerinde yineleme yapabileceğiniz bir yineleyici ve sentinel sağlar.
template<class T>
concept range = requires(T& rg)
{
ranges::begin(rg);
ranges::end(rg);
};
Parametreler
T
Olup olmadığını rangegörmek için test etmek için gereken tür.
Açıklamalar
range gereksinimleri şunlardır:
- ve kullanılarak
std::ranges::begin()yinelenebilirstd::ranges::end() -
ranges::begin()veranges::end()amorti edilmiş sabit süre içinde çalıştırın ve üzerinderangedeğişiklik yapmayın. Amorti edilmiş sabit süre O(1) anlamına gelmez, ancak en kötü durumda bile bir dizi çağrının ortalama maliyetinin O(n^2) veya daha kötü olması yerine O(n) olur. -
[ranges::begin(), ranges::end())geçerli bir aralığı belirtir.
Simple_View
A Simple_View , bazı ranges arabirimlerde kullanılan yalnızca edat kavramıdır. Kitaplıkta tanımlanmamıştır. Yalnızca bazı aralık bağdaştırıcılarının davranışını açıklamaya yardımcı olmak için belirtimde kullanılır.
template<class V>
concept Simple_View = // exposition only
ranges::view<V> && ranges::range<const V> &&
std::same_as<std::ranges::iterator_t<V>, std::ranges::iterator_t<const V>> &&
std::same_as<std::ranges::sentinel_t<V>, std::ranges::sentinel_t<const V>>;
Parametreler
V
Olup olmadığını Simple_Viewgörmek için test etmek için gereken tür.
Açıklamalar
Aşağıdakilerin tümü doğruysa bir görünümdür VSimple_View :
-
Vbir görünümdür -
const Vbir aralıktır -
vHem hem deconst Vaynı yineleyici ve sentinel türlerine sahiptir.
sized_range
A sized_range , amorti edilmiş sabit süre içindeki aralıktaki öğelerin sayısını sağlar.
template<class T>
concept sized_range = range<T> &&
requires(T& t) { ranges::size(t); };
Parametreler
T
Olup olmadığını sized_rangegörmek için test etmek için gereken tür.
Açıklamalar
' sized_range nin gereksinimleri, üzerinde çağrılmasıdır ranges::size :
- Aralığı değiştirmez.
- Amorti edilmiş sabit süre içindeki öğe sayısını döndürür. Amorti edilmiş sabit süre O(1) anlamına gelmez, ancak en kötü durumda bile bir dizi çağrının ortalama maliyetinin O(n^2) veya daha kötü olması yerine O(n) olur.
ve örneklerinden sized_range bazılarıdır std::liststd::vector.
Örnek: sized_range
Aşağıdaki örnek, bir vector değerinin int bir sized_rangeolduğunu gösterir:
// requires /std:c++20 or later
#include <ranges>
#include <iostream>
#include <vector>
int main()
{
std::cout << std::boolalpha << std::ranges::sized_range<std::vector<int>> << '\n'; // outputs "true"
}
view
, view sahip olduğu öğe sayısından bağımsız olarak sürekli taşıma işlemi, atama ve imha işlemlerine sahiptir. Görünümlerin kopya oluşturulabilir veya kopya atanabilir olması gerekmez, ancak atanabilirse, bu işlemlerin de sabit sürede çalıştırılması gerekir.
Sabit zaman gereksinimi nedeniyle, görünümleri verimli bir şekilde oluşturabilirsiniz. Örneğin, adlı intvektör, bir sayının input üçe bölünerek bölünemediğini belirleyen bir işlev ve bir sayının karesini alan bir işlev verildiğinde, deyimi auto x = input | std::views::filter(divisible_by_three) | std::views::transform(square); girişteki sayıların karelerini içeren ve üçe bölünebilen bir görünümü verimli bir şekilde üretir. Görünümleri birlikte | bağlamak, görünümleri oluşturmak olarak adlandırılır. Bir tür kavramı karşılarsa view verimli bir şekilde oluşturulabilir.
template<class T>
concept view = ranges::range<T> && std::movable<T> && ranges::enable_view<T>;
Parametreler
T
Bunun bir görünüm olup olmadığını görmek için test etmek için gereken tür.
Açıklamalar
Görünümü birleştirilebilir hale getiren temel gereksinim, taşımanın/kopyalamanın ucuz olmasıdır. Bunun nedeni, görünümün başka bir görünümle birlikte oluşturulduğunda taşınması/kopyalanmış olmasıdır. Taşınabilir bir aralık olmalı.
ranges::enable_view<T> kavramının semantik gereksinimlerine uyum sağlamak için kullanılan bir özelliktir view . Bir tür şu şekilde kabul edebilir:
- genel ve kesin olmayan bir şekilde bir uzmanlıktan türetilen
ranges::view_interface - boş sınıfından
ranges::view_basegenel ve açık bir şekilde türetilen veya - özelleştirme
ranges::enable_view<T>true
Yazmanız gereken bazı ortak kodları kaydeden varsayılan uygulama da sağladığından view_interface 1. seçenek tercih edilir.
Bu başarısız olursa, 2. seçenek 3. seçenekten biraz daha basittir.
3. seçeneğin avantajı, türün tanımını değiştirmeden mümkün olmasıdır.
viewable_range
A viewable_range , görünüm olan veya bir görünüme dönüştürülebilen bir türdür.
template<class T>
concept viewable_range =
range<T> && (borrowed_range<T> || view<remove_cvref_t<T>>);
Parametreler
T
Bir görünüm olup olmadığını veya bir görünüme dönüştürülebilir olup olmadığını görmek için test edilecek tür.
Açıklamalar
Aralığı görünüme dönüştürmek için kullanın std::ranges::views::all() .