küme parantezleri ile başvuru türü değişkeni üzerine decltype

Dec 15 2020

Aşağıdaki kodu göz önünde bulundurun :

#include <type_traits>

int main() {
    const int& p = 42;
    auto v1 = decltype(p){};
    static_assert(std::is_same_v<decltype(v1), int>);
    
    decltype(p) v2{};
    static_assert(std::is_same_v<decltype(v2), const int&>);
    // auto v3 = X(const int&)X {};
}

Türü v1olarak çıkarılır int. Aynı zamanda türü v2de beklendiği gibi çıkarılır const int&. Sanırım ilk adım, v1bir tür takma adı daha eklemek olarak değerlendirilebilir using T = decltype(p);ve sonra auto v4 = T{};. Bu ifade ( decltype(p){}veya T{}) derleyici tarafından nasıl ele alınır? Bu {}parçanın örnekleme için olduğunu biliyorum , ancak sonuçta ortaya çıkan tür v1bir referans türü değil?

Yine başka bir soru: Açıkça not edilen türü (yerine ) kullanmakla v3aynı türdeki değişkeni bildirmenin bir yolu var mı?v1const int&decltype(p)

Standartla ilgili herhangi bir bağlantı memnuniyetle karşılanacaktır.

Yanıtlar

1 Enlico Dec 15 2020 at 00:48

(Olumsuz oy verenler için: Scott Meyers'den alıntı yapmanın standarttan alıntı yapmaya eşdeğer olmadığını düşündüğünüz için olumsuz oy verdiyseniz, peki ...)

Effective Modern C ++ ' dan okuyabileceğiniz gibi ( bu bağlantıda arayarak ulaşabileceğiniz hata verilerinin bir kısmı ile artırılmış Case 2:ve bu sadece aşağıdaki okumayı daha basit hale getirir, ancak soru için gerekli değildir):

Eğer ParamTypeolmayan bir referans mahiyetinde ise [...] expr'in tür bir referans, referans kısmını yok sayar. [...] exprise const, bunu da anlayın. Eğer öyleyse volatile, bunu da görmezden gelin.

parambildirim belirticisi nerede , sizin durumunuzda sadece auto, yani referans değil.

Başka bir deyişle, v1düz auto(değil auto&), yani kopya yoluyla yaratıyorsunuz , bu yüzden onu referans olan bir varlık ile başlatıp başlatmadığınız, hatta fwiw ile constveya değil ( volatileveya değil, fwiw), farketmez, çünkü onu kopyalıyorsun.

Daha basit durumu düşünün,

int i = 3;
int& p = i;
auto v1 = p;

v1söz konusu olduğu kadarıyla , aynı varlığın bilindiği bir ( i) veya diğer ( p) adla baş harflere dönüştürülmesi gerçekten önemli değil , çünkü o varlığın sahip olduğu değerin bir kopyasını alacaktır.

autotür çıkarımı, şablon türü çıkarımı gibi çalışır (bu durumda ilgili olmayan, çaprazlı başlatıcıyla nasıl başa çıktıklarıyla ilgili bir fark hariç) ve her ikisi için de Scott Meyers'in Etkili Modern C ++ 'sına başvurabilirsiniz .