Soru C ++ cinsinden (x) tipi [duplicate]


Bu sorunun zaten bir cevabı var:

  • decltype ve parantez                     3 cevap                 

Verilen:

decltype(auto) f1()
{
    int x = 0;
    return x;  // decltype(x) is int, so f1 returns int
}
decltype(auto) f2()
{
    int x = 0;
    return (x);  // decltype((x)) is int&, so f2 returns int&
}

(Scott Meyer'in Etkili Modern C ++'sından alınmıştır).

Şimdi, doğru paragrafı bulsaydım, Bölüm 7.1.5.2 Basit tip belirticiler [dcl.type.simple] C ++ standardı diyor ki:

E, bir kimlik ifadesi veya sınıf üyesi erişimiyse (5.2.5 [expr.ref]),   decltype (e), e tarafından adlandırılmış varlığın türü olarak tanımlanır.

ve bu bölümden örnek:

struct A { double x; }

const A* a = new A();

decltype((a->x)); // type is const double&

Şimdi neden merak ediyorum decltype((x)) olduğu sonucuna varıldı int& kitapta.


21
2017-11-02 14:13


Menşei


Neden declype türüne ihtiyacınız var? otomatik yeterlidir .. - David Haim
ama bununla yüzleşelim, cevap muhtemelen standart bir tuhaf kıtanın ne denli davranacağını söyleyen bazı ezoterik kurallardan alıntı yapıyor olacak. - David Haim
@DavidHaim, ezoterik kuralların garip kılıklı nüansları için etiketi ekledi. - Quentin
@DavidHaim Açıkladığınız şey bu sitede sık sık olurken, bu oldukça köşegen olmayan bir durum olan C ++ 11 özelliğinin “bazı ezoterik kuralların garip kıvamı” özelliğini kullanması neredeyse imkansızdı. - Baum mit Augen
Görmek decltype ve parantez - Shafik Yaghmour


Cevaplar:


İlgili standartlar şu şekildedir:

N4140 [dcl.type.simple]/4: Bir ifade için e, tarafından belirtilen tür decltype(e) aşağıdaki gibi tanımlanır:

  • e, saydam olmayan bir kimlik ifadesi veya saydam olmayan bir sınıf üyesi erişimi ise (5.2.5), decltype(e)   tarafından isimlendirilen varlığın türü e. Eğer böyle bir varlık yoksa ya da aşırı yüklenmiş fonksiyonların isimlerini seçerse, program kötü biçimlendirilir;
  • aksi takdirde e bir xvalue, decltype(e) olduğu T&&, nerede T e'nin türüdür;
  • aksi takdirde e bir değer, decltype(e) olduğu T&, nerede T e tür;
  • aksi takdirde, decltype(e) türü e.

Dan beri x bir değerdir ve ifade paranteze edilir, üçüncü kural kullanılır, decltype((x)) olduğu int&.


10
2017-11-02 14:39





decltype bir değişkenin bildirilen türünü veya bir ifadenin "türünü" döndürür (l / r değerini göstermek için bazı referans eklenmiş).

Bu, iki farklı amaç için kullanılmasına izin verir. Bazen bu karışıklığa neden olur, ama ne olduğudır.

Simge x bir değişkendir. Değişkenin tipi int.

Simgeler (x) Hangi değil bir değişken değil, bir değişkenden başka bir şey içeren bir (gerçekten önemsiz) ifade. Gibi, türünün ifade (declype ile belirlenen) (x) olduğu int&.

İfadenin tipi x (decltype'ı size vermek için ikna edebilirseniz; int&ama kuralın decltype(ACTUAL_VAR_NAME) "Kazanır" değişkeninin türünü değerlendirir.

Şimdi, yukarıdakilerin hiçbiri doğru değil. Asıl gerçek, bir derleyicinin hangi türden olduğunu belirlemek için atması gereken adımları açıklayan standart bir alıntıdır. decltype döner. Ancak, etkili bir yalan ve bir standart (standart ifadeler hatalara dönüşmüşse), standardın onunla aynı fikirde olmadığında bir hata olduğunu gösterebilir.


8
2017-11-02 14:41





§ 7.1.6.4 [dcl.spec.auto] (taslak n = 797)

  1. ... Yer tutucu ise   decltype (otomatik)   tip-belirteci   , değişken veya dönüş türünün bildirilen türü   Fonksiyonun tek başına yer tutucu olacaktır. Değişken veya dönüş tipi için çıkarılan tür belirlenir.   açıklandığı gibi   7.1.6.2   başlangıç ​​başlatıcısı,   decltype   .

§ 7.1.6.2 [dcl.type.simple]

  1. Bir ifade için   e   , tarafından belirtilen tür   decltype (e)   aşağıdaki gibi tanımlanır:

-    Eğer   e   bir saydam değil   id-ifadesi   veya saydam olmayan bir sınıf üyesi erişimi (   5.2.5   ),   decltype (e)   tarafından isimlendirilen varlığın türü   e   . Böyle bir varlık yoksa veya   e   bir dizi aşırı yüklenmiş func   Program, kötü biçimlendirilmiş;

-    aksi takdirde   e   bir xvalue,   decltype (e)   olduğu   T &&   , nerede   T   türü   e   ;

-    aksi takdirde   e   bir değer,   decltype (e)   olduğu   T   , nerede   T   türü   e   ;

-    aksi takdirde,   decltype (e)   türü   e

x bir saydam olmayan id ifadesidir ve bu nedenle dönüş tipi tür olarak çıkarılır x: int

(x) olduğu değil bir unparenthesized id-expression böylece kural uygulanmaz. Ancak, olduğu (parantezize edilmiş) bir değer ifade. Bu nedenle, türetilen tür T& nerede T türü x: int&


5
2017-11-02 14:38



@downvoter cevapta bir hata var mı? Bunu nasıl geliştirebilirim? - user2079303


[dcl.spec.auto] / 7, kabaca bir şekilde, dönüş türünün uygulanarak elde edildiğini belirtmektedir. decltype ifadesinde return Beyan. Böylece, yorum olarak önerdiğimiz gibi, decltype((x)). Bir fiendish kuralı adım:

enter image description here

İlk mermi noktasının ifadeden beri geçerli olmadığını unutmayın. olduğu parantez. Biz olsun int&.


Uygulamaları arasındaki bu ayrım decltype Düz tanımlayıcılar ve parantez içinde olanlar ilgili kağıdın revizyonu 6 ile tanıtıldı. Görmek revizyon 5, §2.3:

Tarafından belirtilen tür decltype(e) aşağıdaki gibi tanımlanır:

  1. Eğer e formda (e1), decltype(e) olarak tanımlanır decltype(e1).

Bunun arkasındaki gerekçelendirme muhtemelen aşağıdaki gibidir: Yazma (x), programcı niyetinde decltype işleneni bir isim olarak değil, bir değer olarak ele almayı - değer kategorisini dikkate alarak.


5
2017-11-02 14:40





@Columbo'nun işaret ettiği gibi (a-> x) bir ifade ve bu ifade olarak ele alınacaktır. olduğu  const nitelikli, çünkü * a bir const.

Bunu düşünelim

decltype((a->x)); 

değildi const nitelikli.

Sonra ör. bu

decltype((a->x)) ref = (a->x); 

* bir const niteleyicisini örtük olarak kaldıracaktır, çünkü * a'nın x değeri değişebilir olur ref.


0
2017-11-02 15:16