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ürle ş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 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.
Yineleyici kavramları ad alanında std tanımlanır ve üst bilgi dosyasında bildirilir <iterator> . Bunlar, aralık bağdaştırıcılarının, görünümlerin vb. bildirimlerinde kullanılır.
Altı yineleyici kategorisi vardır. Bunlar, Aralık kavramları altında listelenen aralık kategorileri ile doğrudan ilişkilidir.
Aşağıdaki yineleyici kavramlar, özelliği artırma sırasına göre listelenmiştir.
input_or_output_iterator , yetenek hiyerarşisinin alt ucundadır ve contiguous_iterator üst uçtadır. Hiyerarşide daha yüksek yineleyiciler genellikle daha düşük olanlar yerine kullanılabilir, ancak tam tersi değildir. Örneğin, yineleyici random_access_iterator yerine bir yineleyici kullanılabilir forward_iterator, ancak tersi kullanılamaz. Özel durum, input_iteratoryerine yazılamadığı için kullanılamayan output_iterator şeklindedir.
Aşağıdaki tabloda , "Multi-pass", yineleyicinin aynı öğeyi birden çok kez yeniden ziyaret edip etmediğini ifade eder. Örneğin, vector::iterator çok geçişli bir yineleyicidir çünkü yineleyicinin bir kopyasını oluşturabilir, koleksiyondaki öğeleri okuyabilir, sonra yineleyiciyi kopyadaki değere geri yükleyebilir ve aynı öğeleri yeniden ziyaret edebilirsiniz. Yineleyici tek geçişliyse koleksiyondaki öğeleri yalnızca bir kez ziyaret edebilirsiniz.
Aşağıdaki tabloda ,"Örnek türler", kavramı karşılayan koleksiyonları/yineleyicileri ifade eder.
| Yineleyici kavramı | Açıklama | Yön | Okuma/yazma | Çoklu geçiş | Örnek türler |
|---|---|---|---|---|---|
input_or_output_iterator
C++20 |
Yineleyici kavramı taksonomisinin temeli. | İleri | Okuma/yazma | hayır |
istream_iterator, ostream_iterator |
output_iterator
C++20 |
Yazabileceğiniz bir yineleyici belirtir. | İleri | Yazmak | hayır |
ostream, inserter |
input_iterator
C++20 |
Bir kereden okuyabileceğiniz bir yineleyici belirtir. | İleri | Okundu | hayır |
istream, istreambuf_iterator |
forward_iterator
C++20 |
Birden çok kez okuyabilen (ve büyük olasılıkla yazabilen) bir yineleyici belirtir. | İleri | Okuma/yazma | evet |
vector, list |
bidirectional_iterator
C++20 |
Hem ileri hem de geri okuyabileceğiniz ve yazabileceğiniz bir yineleyici belirtir. | İleri veya geri | Okuma/yazma | evet |
list, set, multiset, map ve multimap. |
random_access_iterator
C++20 |
Dizine göre okuyabileceğiniz ve yazabileceğiniz bir yineleyici belirtir. | İleri veya geri | Okuma/yazma | evet |
vector, array, deque |
contiguous_iterator
C++20 |
Öğeleri bellekte sıralı olan, aynı boyutta olan ve işaretçi aritmetiği kullanılarak erişilebilen bir yineleyici belirtir. | İleri veya geri | Okuma/yazma | evet |
array, vector, string. |
Diğer yineleyici kavramlar şunlardır:
| Yineleyici kavramı | Açıklama |
|---|---|
sentinel_for
C++20 |
Bir türün yineleyici türü için bir sentinel olduğunu belirtir. |
sized_sentinel_for
C++20 |
Bir yineleyicinin ve sentinel değerinin, sabit süredeki farklarını bulmak için çıkarılabildiğini (kullanılarak -) belirtir. |
bidirectional_iterator
A bidirectional_iterator , ileri ve geri okumayı ve yazmayı destekler.
template<class I>
concept bidirectional_iterator =
forward_iterator<I> &&
derived_from<ITER_CONCEPT(I), bidirectional_iterator_tag> &&
requires(I i) {
{--i} -> same_as<I&>;
{i--} -> same_as<I>;
};
Parametreler
I
Olup olmadığını bidirectional_iteratortest etmek için yineleyici.
Açıklamalar
A bidirectional_iterator , 'nin özelliklerine forward_iteratorsahiptir, ancak geriye doğru da yineleyebilir.
ile bidirectional_iteratorsetkullanılabilecek kapsayıcılara örnek olarak , , multisetmap, multimap, vectorve listverilebilir.
Örnek: bidirectional_iterator
Aşağıdaki örnek, bidirectional_iterator bir içeren kavramını vector<int>bidirectional_iteratorgöstermek için kullanır:
// requires /std:c++20 or later
#include <iostream>
#include <vector>
int main()
{
std::cout << std::boolalpha << std::bidirectional_iterator<std::vector<int>::iterator> << '\n'; // outputs "true"
// another way to test
std::vector<int> v = {0,1,2};
std::cout << std::boolalpha << std::contiguous_iterator<decltype(v)::iterator>; // outputs true
}
contiguous_iterator
Öğeleri bellekte sıralı olan, aynı boyutta olan ve işaretçi aritmetiği kullanılarak erişilebilen bir yineleyici belirtir.
template<class I>
concept contiguous_iterator =
random_access_iterator<I> &&
derived_from<ITER_CONCEPT(I), contiguous_iterator_tag> &&
is_lvalue_reference_v<iter_reference_t<I>> &&
same_as<iter_value_t<I>, remove_cvref_t<iter_reference_t<I>>> &&
requires(const I& i) {
{ to_address(i) } -> same_as<add_pointer_t<iter_reference_t<I>>>;
};
Parametreler
I
Olup olmadığını contiguous_iteratorgörmek için test etmek için gereken tür.
Açıklamalar
contiguous_iterator öğeleri bellekte sıralı olarak yerleştirildiğinden ve aynı boyutta olduğundan, öğesine işaretçi aritmetiği tarafından erişilebilir. bazı örnek olarak contiguous_iteratorarray, vectorve stringverilebilir.
Örnek: contiguous_iterator
Aşağıdaki örnekte, bir 'in bir olduğunu contiguous_iteratorvector<int>göstermek için kavramı kullanılırcontiguous_iterator:
// requires /std:c++20 or later
#include <iostream>
#include <vector>
int main()
{
// Show that vector<int> has a contiguous_iterator
std::cout << std::boolalpha << std::contiguous_iterator<std::vector<int>::iterator> << '\n'; // outputs "true"
// another way to test
std::vector<int> v = {0,1,2};
std::cout << std::boolalpha << std::contiguous_iterator<decltype(v)::iterator>; // outputs true
}
forward_iterator
ve input_iterator'nin özelliklerine output_iterator sahiptir. Bir koleksiyon üzerinde birden çok kez yinelemeyi destekler.
template<class I>
concept forward_iterator =
input_iterator<I> &&
derived_from<ITER_CONCEPT(I), forward_iterator_tag> &&
incrementable<I> &&
sentinel_for<I, I>;
Parametreler
I
Olup olmadığını forward_iteratortest etmek için yineleyici.
Açıklamalar
A forward_iterator yalnızca ileri gidebilir.
ile forward_iteratorvectorkullanılabilecek kapsayıcılara örnek olarak , , listunordered_set, unordered_multiset, unordered_mapve unordered_multimapverilebilir.
Örnek: forward_iterator
Aşağıdaki örnekte, bir 'in bir olduğunu forward_iteratorvector<int>göstermek için kavramı kullanılırforward_iterator:
// requires /std:c++20 or later
#include <iostream>
#include <vector>
int main()
{
// Show that vector has a forward_iterator
std::cout << std::boolalpha << std::forward_iterator<std::vector<int>::iterator> << '\n'; // outputs "true"
// another way to test
std::vector<int> v = {0,1,2};
std::cout << std::boolalpha << std::forward_iterator<decltype(v)::iterator>; // outputs true
}
input_iterator
, input_iterator en az bir kez okuyabileceğiniz bir yineleyicidir.
template<class I>
concept input_iterator =
input_or_output_iterator<I> &&
indirectly_readable<I> &&
requires { typename ITER_CONCEPT(I); } &&
derived_from<ITER_CONCEPT(I), input_iterator_tag>;
Parametreler
I
Olup olmadığını input_iteratorgörmek için test etmek için türü.
Açıklamalar
begin() Birden çok kez çağrılması input_iterator tanımsız davranışla sonuçlanır. Yalnızca modellerin input_iterator çok geçişli olmadığı bir tür. Örneğin, standart girişten (cin) okumayı göz önünde bulundurun. Bu durumda, geçerli öğeyi yalnızca bir kez okuyabilir ve zaten okuduğunuz karakterleri yeniden okuyamazsınız. Yalnızca input_iterator ileri doğru okur, geriye doğru değil.
Örnek: input_iterator
Aşağıdaki örnek, bir 'in bir 'e sahip input_iteratorolduğunu istream_iterator göstermek için kavramını kullanırinput_iterator:
// requires /std:c++20 or later
#include <iostream>
int main()
{
// Show that a istream_iterator has an input_iterator
std::cout << std::boolalpha << std::input_iterator<std::istream_iterator<int>>; // outputs true
}
input_or_output_iterator
Bir input_or_output_iterator , yineleyici kavram taksonomisinin temelidir. Bir yineleyicinin başvuruyu kaldırmayı ve artırmayı destekler. Her yineleyici modeli input_or_output_iterator.
template<class I>
concept input_or_output_iterator =
requires(I i) {
{ *i } -> can-reference;
} &&
weakly_incrementable<I>;
Parametreler
I
Olup olmadığını input_or_output_iteratorgörmek için test etmek için türü.
Açıklamalar
Kavram can-reference , türün I bir başvuru, işaretçi veya örtük olarak başvuruya dönüştürülebilecek bir tür olduğu anlamına gelir.
Örnek: input_or_output_iterator
Aşağıdaki örnek, input_or_output_iterator bir içeren kavramını vector<int>input_or_output_iteratorgöstermek için kullanır:
// requires /std:c++20 or later
#include <iostream>
int main()
{
// Show that a vector has an input_or_output_iterator
std::cout << std::boolalpha << std::input_or_output_iterator<std::vector<int>::iterator> << '\n'; // outputs true
// another way to test
std::vector<int> v = {0,1,2};
std::cout << std::boolalpha << std::input_or_output_iterator<decltype(v)::iterator>; // outputs true
}
output_iterator
, output_iterator yazabileceğiniz bir yineleyicidir.
template<class I, class T>
concept output_iterator =
input_or_output_iterator<I> &&
indirectly_writable<I, T> &&
requires(I i, T&& t) {
*i++ = std::forward<T>(t);
};
Parametreler
I
Olup olmadığını output_iteratorgörmek için test etmek için türü.
T
Yazacak değerlerin türü.
Açıklamalar
Bir output_iterator tek geçiştir. Yani, aynı öğeye yalnızca bir kez yazabilir.
Örnek: output_iterator
Aşağıdaki örnek, output_iterator bir içeren kavramını vector<int>output_iteratorgöstermek için kullanır:
// requires /std:c++20 or later
#include <iostream>
#include <vector>
int main()
{
// Show that vector<int> has an output_iterator
std::cout << std::boolalpha << std::output_iterator<std::vector<int>::iterator, int> << "\n"; // outputs "true"
// another way to test
std::vector<int> v = {0,1,2,3,4,5};
std::cout << std::boolalpha << std::output_iterator<decltype(v)::iterator, int>; // outputs true
}
random_access_iterator
bir random_access_iterator , dizine göre okuyabilir veya yazabilir.
template<class I>
concept random_access_iterator =
bidirectional_iterator<I> &&
derived_from<ITER_CONCEPT(I), random_access_iterator_tag> &&
totally_ordered<I> &&
sized_sentinel_for<I, I> &&
requires(I i, const I j, const iter_difference_t<I> n) {
{ i += n } -> same_as<I&>;
{ j + n } -> same_as<I>;
{ n + j } -> same_as<I>;
{ i -= n } -> same_as<I&>;
{ j - n } -> same_as<I>;
{ j[n] } -> same_as<iter_reference_t<I>>;
};
Parametreler
I
Olup olmadığını random_access_iteratorgörmek için test etmek için gereken tür.
Açıklamalar
, random_access_iterator , input_iteratoroutput_iteratorve forward_iteratorözelliklerine bidirectional_iteratorsahiptir.
bazı örnek olarak random_access_iteratorvector, arrayve dequeverilebilir.
Örnek: random_access_iterator
Aşağıdaki örnekte, a'nın vector<int> bir öğesi olduğu gösterilmektedir random_access_iterator:
// requires /std:c++20 or later
#include <iostream>
#include <vector>
int main()
{
// Show that vector<int> has a random_access_iterator
std::cout << std::boolalpha << std::random_access_iterator<std::vector<int>::iterator> << '\n'; // outputs "true"
// another way to test
std::vector<int> v = {0,1,2};
std::cout << std::boolalpha << std::random_access_iterator<decltype(v)::iterator>; // outputs true
}
sentinel_for
Türün yineleyici için bir sentinel olduğunu belirtir.
template<class S, class I>
concept sentinel_for =
semiregular<S> &&
input_or_output_iterator<I> &&
weakly-equality-comparable-with <S, I>;
Parametreler
I
Yineleyici türü.
S
için bir sentinel olup olmadığını test etmek için Ikullanılacak tür.
Açıklamalar
Sentinel, yineleyicinin sona ulaşıp ulaşmadığını belirlemek için yineleyiciyle karşılaştırılabilir bir türdür. Bu kavram, bir türün , , input_or_output_iteratorinput_iteratoroutput_iteratorforward_iteratorve bidirectional_iteratoriçeren random_access_iteratortürlerden contiguous_iterator biri için bir sentinel olup olmadığını belirler.
Örnek: sentinel_for
Aşağıdaki örnek için sentinel_for bir sentinel olduğunu vector<int>::iterator göstermek için vector<int>kavramını kullanır:
// requires /std:c++20 or later
#include <iostream>
#include <vector>
int main()
{
std::vector<int> v = {0, 1, 2};
std::vector<int>::iterator i = v.begin();
// show that vector<int>::iterator is a sentinel for vector<int>
std::cout << std::boolalpha << std::sentinel_for<std::vector<int>::iterator, decltype(i)>; // outputs true
}
sized_sentinel_for
Bir yineleyicinin ve sentinel değerinin, farkı bulmak için sabit bir süre içinde kullanılarak - çıkarılabildiğini test edin.
template<class S, class I>
concept sized_sentinel_for =
sentinel_for<S, I> &&
!disable_sized_sentinel_for<remove_cv_t<S>, remove_cv_t<I>> &&
requires(const I& i, const S& s) {
{s - i} -> same_as<iter_difference_t<I>>;
{i - s} -> same_as<iter_difference_t<I>>;
};
Parametreler
I
Yineleyici türü.
S
Test etmek için sentinel türü.
Örnek: sized_sentinel_for
Aşağıdaki örnek, bir sized_sentinel_for için sentinel değerinin vektör yineleyicisinden sabit bir süre içinde çıkarılabildiğini doğrulamak için kavramını kullanırvector<int>:
// requires /std:c++20 or later
#include <iostream>
#include <vector>
int main()
{
std::vector<int> v = { 1, 2, 3 };
std::vector<int>::iterator i = v.begin();
std::vector<int>::iterator end = v.end();
// use the sized_sentinel_for concept to verify that i can be subtracted from end in constant time
std::cout << std::boolalpha << std::sized_sentinel_for<decltype(end), decltype(i)> << "\n"; // outputs true
std::cout << end - i; // outputs 3
}
Ayrıca bkz.
Aralık kavramları
Aralık bağdaştırıcıları
Sınıfları görüntüleme