Bu eski bir C ++ tarzı yapıcı mı?


17

İşte bir parça C ++ kodu.

Bu örnekte, birçok kod bloğu yapıcı çağrılarına benzemektedir. Ne yazık ki, # 3 blok kodu değil ( https://godbolt.org/z/q3rsxn ve https://cppinsights.io kullanarak kontrol edebilirsiniz ).

Bence, eski bir C ++ gösterimi ve {} (cf # 4) kullanarak yeni C ++ 11 inşaat gösteriminin tanıtımını açıklayabilir.

T(i)Bir yapıcı gösterimine çok yakın, ama kesinlikle çok farklı bir anlam açıklamanız var mı?

struct T {
   T() { }
   T(int i) { }
};

int main() {
  int i = 42;
  {  // #1
     T t(i);     // new T named t using int ctor
  }
  {  // #2
     T t = T(i); // new T named t using int ctor
  }
  {  // #3
     T(i);       // new T named i using default ctor
  }
  {  // #4
     T{i};       // new T using int ctor (unnamed result)
  }
  {  // #5
     T(2);       // new T using int ctor (unnamed result)
  }
}

Not: bu nedenle T(i)(# 3) T i = T();


1
Bence tüm ifadelerin doğru.
Arne J


Ekleyin: derleyici sadece bunu sorarsan bilmeniz gereken hemen hemen tüm söyleyecektir Not -Wallve almak " warning: parentheses were disambiguated as redundant parentheses around declaration of variable named 'i' [-Wvexing-parse]" clang gelen, ya da biraz daha az motive " warning: unnecessary parentheses in declaration of 'i' [-Wparentheses]" gcc dan .
Max Langhof

@QuentinUK bu bağlantı için teşekkür ederim. Ben fonksiyonlar (örneğin T t()) hakkında farkındaydım ama çok basit beyan ifadeleri için değil. Elbette, bu can sıkıcı olabilir .
Pascal H.

Yanıtlar:


17

İfade:

T(i);

şuna eşittir:

T i;

Başka bir deyişle, itype adında bir değişken bildirir T. Bunun nedeni, bazı yerlerde bildirimlerde parantezlere izin verilmiş olmasıdır (bildiricilerin bağlanmasını değiştirmek için) ve bu ifade bir bildirim olarak ayrıştırılabildiğinden, bir bildirimdir (bir ifade olarak daha anlamlı olsa bile).


Öyleyse, bu sadece int(i)bir intisim beyan eden C spesifikasyonlarından miras alınan bir yorumlama seçeneği imi?
Pascal H.

@PascalH. Belli bir bakış açısından, bu doğru olabilir. Stroustrup, D&E'de C ++ için alternatif, daha sezgisel bir bildirim sözdizimi olduğunu düşündüğünü yazdı. C ++, C ile geriye dönük olarak uyumlu olmak zorunda olmasaydı, belki de alternatif sözdizimine sahip olacaktı ve böylece ifadelerdeki potansiyel belirsizliği önleyecektir.
Brian

-1

Derleyici'de neler olduğunu görmek için Derleyici Gezgini'ni kullanabilirsiniz .

# 1, # 2 # 4 ve # 5'in aynı şeyi yaptığını, ancak # 3'ün diğer kurucuya (temel nesne kurucusu) çağırdığını görebilirsiniz.

Herkesin bir açıklaması var mı?

Montajcı kodu:

::T() [base object constructor]:
        push    rbp
        mov     rbp, rsp
        mov     QWORD PTR [rbp-8], rdi
        nop
        pop     rbp
        ret
T::T(int):
        push    rbp
        mov     rbp, rsp
        mov     QWORD PTR [rbp-8], rdi
        mov     DWORD PTR [rbp-12], esi
        nop
        pop     rbp
        ret
main:
        push    rbp
        mov     rbp, rsp
        sub     rsp, 16
        mov     DWORD PTR [rbp-4], 42
// #1
        mov     edx, DWORD PTR [rbp-4]
        lea     rax, [rbp-7]
        mov     esi, edx
        mov     rdi, rax
        call    T::T(int)
// #2
        mov     edx, DWORD PTR [rbp-4]
        lea     rax, [rbp-8]
        mov     esi, edx
        mov     rdi, rax
        call    T::T(int)
// #3
        lea     rax, [rbp-9]
        mov     rdi, rax
        call    T::T() [complete object constructor]
// #4
        mov     edx, DWORD PTR [rbp-4]
        lea     rax, [rbp-6]
        mov     esi, edx
        mov     rdi, rax
        call    T::T(int)
// #5
        lea     rax, [rbp-5]
        mov     esi, 2
        mov     rdi, rax
        call    T::T(int)

        mov     eax, 0
        leave
        ret
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.