2010-02-16 30 views
7

Observation: the codes pasted below were tested only with GCC 4.4.1, and I'm only interested in them working with GCC.Nesne inşaat/İleri fonksiyon bildirimi belirsizlik

Merhaba,

Ben anlamadım bir nesne inşaat deyimi içine düştüğüm sadece birkaç kez değildi ve sadece bugün onun hangi belirsizliğin ortaya çıktığını fark ettim. Nasıl çoğaltılacağını açıklayacağım ve düzeltmenin bir yolu olup olmadığını öğrenmek istiyorum (C++ 0x izinli). İşte gidiyor.

Kurucunun yalnızca bir argüman aldığı bir sınıf olduğunu ve bu argümanın türünün varsayılan kurucuya sahip başka bir sınıf olduğunu varsayalım. Ör:

Class c(ArgType()); // is this an object construction or a forward declaration 
        // of a function "c" returning `Class` and taking a pointer 
        // to a function returning `ArgType` and taking no arguments 
        // as argument? (oh yeh, loli haets awkward syntax in teh 
        // saucecode) 

Ben bir nesne inşaat olduğunu söylüyorsun ama derleyici bir ileri ilanıdır ısrar: Ben yığın tip Class bir nesne oluşturmak çalışırsanız

struct ArgType {}; 

class Class 
{ 
public: 
    Class(ArgType arg); 
}; 

, ben bir belirsizlik olsun işlev gövdesinin içinde. Hala almayanlar için, tam olarak bir örnek aşağıdadır:

#include <iostream> 

struct ArgType {}; 
struct Class {}; 

ArgType func() 
{ 
    std::cout << "func()\n"; 
    return ArgType(); 
} 

int main() 
{ 
    Class c(ArgType()); 

    c(func); // prints "func()\n" 
} 

Class c(ArgType funcPtr()) // Class c(ArgType (*funcPtr)()) also works 
{ 
    funcPtr(); 
    return Class(); 
} 

Çok iyi, yeterli örnekler. Herhangi bir şey, anti-deyimsiz bir şey yapmadan (bir kütüphane geliştiricisiyim ve deyimsel kütüphaneler gibi insanlar) bunu yapmama yardım edebilir mi?

- düzenle

Boşver. Bu, Most vexing parse: why doesn't A a(()); work?'un bir kopyasıdır.

Teşekkürler sbi.

+0

Kodunuz ++ g benim için derler örneklere - Çalışmadığınız gerektiğini düşünüyorum hangi bit? –

+0

Çalışmak veya çalışmamak meselesi değil. Sorun şu ki, sadece 'Class' türünde bir nesneyi oluşturmak ve kurucusunu inline yapılmış bir argtype türünden bir nesneyi aktarmak istedim .. Ama ileriye dönük bir beyan olarak kabul ediyor. Çalışmak istediğim kodu ekleyeceğim ama sadece bir saniye yapamam. –

+0

Unut bunu, Neil. Sbi'nin cevabına bak, tam olarak benim problemim. –

cevap

5

Bu "C++ 'nin en çok rahatsız edici ayrıştırması" olarak bilinir. Bkz. here, here ve here. ,

Class c(ArgType {}); 

Basit, anlaşılır ve tamamen kütüphanenin kullanıcı üzerindeki yükü koyar: dayanarak

1

doğru cevap (muhtemelen) için tanımını değiştirmek için, "C++ 0x izin" yazar değil!

Düzenleme: Evet, ctor çağrılır - C++ 0x, başlatıcı listelerini sınırlamak için Liste Başlatma özelliğini belirsiz bir yol olarak ekler. Numunenizde olduğu gibi yanlış bir şekilde ayrıştırılamaz, aksi halde parantez kullanmış olmanız, kabaca aynıdır. §8.5.4/3 altındaki üçüncü madde işareti olan N3000. Bir başlatıcı listesini tek bir argüman olarak almak için bir ctor yazabilirsiniz veya başlatıcı listesindeki öğeler bağımsız değişkenler ile bağımsız değişkenler ile eşleştirilebilir.

+0

Bekle .. ama bu yapıcıyı çağırmazdı, değil mi? –

+1

Aslında bu GCC 4.4.1 için kabul edilebilir görünmüyor. Ancak, diğer kombinasyonlar şunlardır: 'Sınıf c {ArgType {}};' veya 'Sınıf c {ArgType()};' Ve yapıcıyı çağırmak için C++ olmayan bir sürüm ekleme: 'Sınıf c ((ArgType())); ' – UncleBens

1

Biraz basitleştirelim.

int f1(); 

Bu nedir? Derleyici (ve I), bir tamsayı döndüren bir işlev için ileriye dönük bir beyan olduğunu söyler.

Bu nasıl?

int f2(double); 

derleyici (ve) o çifte argüman alıp bir int döndüren bir fonksiyon için bir ileri beyanı olduğunu söylüyorlar.

Yani bunun çalıştı vardır:

ClassType c = ClassType(ArgType()); 

kontrol dışarı C++ sss lite explanations için constructors ve