C ++ 20 tanıtır std::common_reference
. Amacı nedir? Birisi buna bir örnek verebilir mi?
C ++ 20 tanıtır std::common_reference
. Amacı nedir? Birisi buna bir örnek verebilir mi?
Yanıtlar:
common_reference
STL'nin proxy yineleyicilerini barındıran yineleyicilerin kavramsallaştırılmasıyla ilgili çabalarımdan çıktı.
STL'de, yineleyicilerin ilişkili iki tür özel ilgi alanı vardır: reference
ve value_type
. Eski yineleyici en dönüş türü olan operator*
ve value_type
dizinin elemanları (const olmayan, referans olmayan) türüdür.
Genel algoritmaların genellikle böyle şeyler yapma ihtiyacı vardır:
value_type tmp = *it;
... biz olması gerektiğini biliyorum bazı Bu iki tip arasındaki ilişki. Proxy olmayan yineleyiciler için ilişki basittir: reference
her zaman value_type
, isteğe bağlı olarak const ve başvuru nitelikli. Kavramın tanımlanmasına yönelik erken girişimlerInputIterator
, ifadenin *it
dönüştürülebilir olmasını const value_type &
ve çoğu ilginç yineleyici için yeterli olmasını gerektiriyordu.
C ++ 20'deki yineleyicilerin bundan daha güçlü olmasını istedim. Örneğin, zip_iterator
kilit adımında iki diziyi yineleyen a'nın ihtiyaçlarını düşünün . A'dan vazgeçtiğinizde , iki yineleyicinin türünden zip_iterator
bir geçici alırsınız . Yani, a ve a şu ilişkili türlere sahip olacaktır:pair
reference
zip
vector<int>
vector<double>
zip
yineleyicinin reference
: pair<int &, double &>
zip
yineleyicinin value_type
:pair<int, double>
Gördüğünüz gibi, bu iki tür sadece üst düzey cv- ve ref yeterlilikleri ekleyerek birbirleriyle ilişkili değildir. Ve yine de iki türün keyfi olarak farklı olmasına izin vermek yanlış geliyor. Açıkçası burada bir ilişki var. Fakat ilişki nedir ve yineleyiciler üzerinde çalışan genel algoritmalar iki tür hakkında güvenli bir şekilde ne kabul edebilir?
C ++ 20'de cevabı için olmasıdır herhangi vekil veya olmasın geçerli yineleyici tip, tür reference &&
ve value_type &
bir paylaşma ortak referansı . Başka bir deyişle, bazı Yineleyici için it
bazı tip var CR
iyi biçimli aşağıdakileri yapar:
void foo(CR) // CR is the common reference for iterator I
{}
void algo( I it, iter_value_t<I> val )
{
foo(val); // OK, lvalue to value_type convertible to CR
foo(*it); // OK, reference convertible to CR
}
CR
ortak referanstır. Tüm algoritmalar bu türün varlığına güvenebilir ve bunu std::common_reference
hesaplamak için kullanabilir .
Yani, common_reference
C ++ 20'de STL'de oynayan rol budur . Genel olarak, genel algoritmalar veya proxy yineleyicileri yazmıyorsanız, güvenle yok sayabilirsiniz. Yineleyicilerin sözleşmeden doğan yükümlülüklerini yerine getirmelerini sağlayan kapakların altındadır.
EDIT: OP de bir örnek istedi. Bu yapmacık biraz, ama onun C ++ 20 hayal ve rastgele erişimli aralığı verilir r
Çeşidi R
Bir şey bilmiyormuş hangi ve istediğiniz sort
aralıkta.
Ayrıca, bazı nedenlerden dolayı, monomorfik bir karşılaştırma fonksiyonu kullanmak istediğinizi düşünün std::less<T>
. (Belki ettik aralığı tip silinir ve ayrıca karşılaştırma işlevi yazın-silmek ve bir içinden geçmeleri gerekiyor virtual
? Yine, bir streç.) Ne olmalıdır T
olmak std::less<T>
? Bunun için common_reference
, ya da iter_common_reference_t
onun açısından uygulanan yardımcıyı kullanırdınız .
using CR = std::iter_common_reference_t<std::ranges::iterator_t<R>>;
std::ranges::sort(r, std::less<CR>{});
Aralıkta r
proxy yineleyicileri olsa bile, bunun çalışması garanti edilir .
pair<T&,U&>
ve pair<T,U>&
ortak bir referansı olacaktır ve basitçe olacaktır pair<T&,U&>
. Ancak, için std::pair
, hiçbir dönüşüm vardır pair<T,U>&
için pair<T&,U&>
, böyle bir dönüşüm ilkesinin ses olsa. (Bu arada, zip
C ++ 20'de bir görüşümüz yok .)
pair
Amacı için özel olarak tasarlanabilecek bir tür yerine bir zip yineleyicisinin kullanmasının bir nedeni var mı? , gerektiği gibi uygun örtülü dönüşümlerle?
std::pair
; uygun dönüşümleri olan herhangi bir uygun çift benzeri tip yapar ve range-v3 böyle bir çift benzeri tip tanımlar. Komitede LEWG, Standart Kütüphane'ye std::pair
, sadece std::pair
iş yapmanın artıları ve eksileri hakkında gereken özen göstermeden, normatif olsun veya olmasın, neredeyse ama tam olmayan bir tür ekleme fikrini beğenmedi .
tuple
, pair
, tomato
, to
- MAH
- to
. pair
Birlikte elemanları erişebilmesi bu güzel özelliği vardır .first
ve .second
. Yapısal bağlamalar, tuple
s ile çalışmanın garipliğinin bazılarına yardımcı olur , ancak hepsi değil.