2015-04-28 11 views
6

Der obige Code funktioniert nicht. Tatsächlich beschwert sich das konstruierte Standardobjekt f im Konstruktor Foo, dass der Wert val im Geltungsbereich nicht deklariert ist. Ich verstehe nicht, warum es nicht erklärt wird.Nicht deklarierte Variable in default-konstruiertem Objekt im Konstruktor

struct Foo2 
{ 
    Foo2(int val) 
    {} 
}; 

struct Foo 
{ 
    Foo(int val, Foo2 f = Foo2(val)) 
    {} 
}; 

int main() 
{ 
    Foo f(1); 
    return 0; 
} 
+1

Sie keine Parameter in Standardparameter verwenden können. – chris

+2

Diese Frage enthält keine Standardkonstruktoren. –

Antwort

5

Nach dem C++ Standard (8.3.6 Standardargumente):

9 Standardargumente werden jedes Mal t ausgewertet Die Funktion wird aufgerufen. Die Reihenfolge der Auswertung von Funktionsargumenten ist nicht spezifiziert. Daher dürfen Parameter einer Funktion nicht in einem Standardargument verwendet werden, auch wenn sie nicht ausgewertet werden. Parameter einer -Funktion, die vor einem Standardargument deklariert wurde, befinden sich im Gültigkeitsbereich und können Namespace- und Klassenmembernamen ausblenden.

In jedem C++ (nicht nur C++ 2014) können Sie den Konstruktor überladen. Zum Beispiel

struct Foo 
{ 
    Foo(int val) 
    { Foo2 f(val); /*...*/ } 
    Foo(int val, Foo2 f) 
    {} 
}; 

Oder können Sie eine Delegierung Konstruktor verwenden (wenn Ihr Compiler den neuen Standard unterstützt)

struct Foo 
{ 
    Foo(int val) : Foo(val, Foo2(val)) 
    {} 
    Foo(int val, Foo2 f) 
    {} 
}; 
2

So funktioniert die Sprache; Standardargumente können nicht von anderen Parametern abhängen, da die Reihenfolge ihrer Initialisierung nicht angegeben ist.

In C++ 11 oder höher können Sie mit einer Überlastung dieses Problem umgehen:

Foo(int val) : Foo(val, Foo2(val)) {} 
+0

Oder Sie können Überladung verwenden. – refi64

+1

@ kirbyfan64sos Was ist das dann? – LogicStuff

+2

@ kirbyfan64sos: Ich benutze Überladung. –

0
struct Foo2 
{ 
    int x; 
    Foo2(int val): x(val) {} 
}; 

struct Foo 
{ 
    int y; 
    Foo2 f2; 
    Foo(int val, Foo2 f): y(val), f2(f) {} 
    Foo(int val): y(val), f2(val) {} 
}; 

int main() 
{ 
    Foo f(1); 
} 
+1

Das setzt voraus, dass 'f2' eine Mitgliedsvariable von' Foo' ist. – Beta

0

Sie Vorlagen, diese lösen können:

struct Foo2 
{ 
    Foo2(int val) 
    {} 
}; 

template <int val> 
struct Foo 
{ 
    Foo(Foo2 f = Foo2(val)) 
    {} 
}; 

int main() 
{ 
    Foo<1> f = Foo<1>(); 
    return 0; 
} 
+0

Ja, ich weiß, aber ich will 'val' eine Laufzeitvariable sein –

+1

Ahh, das hättest du in erster Linie sagen sollen. –

Verwandte Themen