2009-12-10 7 views
33

Ich konnte keine eindeutige Antwort finden, obwohl das möglicherweise daran liegt, dass ich nicht die richtigen Suchbegriffe verwendet habe. Bitte leiten Sie mich dann um, wenn das der Fall ist. Ist es möglich, vorherige Argumente in einer Funktionsparameterliste als Standardwert für spätere Argumente in der Parameterliste zu verwenden? Zum BeispielC/C++ - Standardargument als vorheriges Argument

void f(int a, int b = a, int c = b); 

Wenn dies möglich ist, gibt es irgendwelche Regeln der Verwendung? Irgendein Unterschied zwischen C und C++?

+6

Um diesen Teil Ihrer Frage zu beantworten, gibt es ** keine ** Vorstellung von Standard-Argument in C. –

Antwort

52

Die Antwort nein ist, kann man nicht. Sie könnten das Verhalten erhalten Sie Überlastungen verwenden möchten:

void f(int a, int b, int c); 
inline void f(int a, int b) { f(a,b,b); } 
inline void f(int a)  { f(a,a,a); } 

Was die letzte Frage ist C nicht Standardparameter überhaupt ermöglichen.

+1

Warum haben Sie nur zwei der Funktionen inline? –

+5

@DavidDoria: Wir haben keine Ahnung, ob die Hauptüberlastung inline sein kann oder sollte - das geht über den Rahmen der Frage hinaus. Die anderen nennen einfach die Hauptüberlastung und können daher leicht inline sein. –

25

Nein, das ist nicht legal C++. Dies wird in Abschnitt 8.3.6/9 des C++ Standard:

Default arguments are evaluated each time the function is called. The order of evaluation of function arguments is unspecified. Consequently, parameters of a function shall not be used in default argument expressions, even if they are not evaluated.

und:

int f(int a, int b = a); // error: parameter a used as default argument

Und C89 zumindest nicht Standard-Parameterwerte unterstützen.

3

Dies ist nicht möglich

2

Nein, das geht nicht.
Sie erhalten sicher eine Fehlermeldung "Lokale Variable wird in diesem Kontext möglicherweise nicht angezeigt".

7

Als potenzielles Problem zu umgehen, könnten Sie tun:

const int defaultValue = -999; // or something similar 

void f(int a, int b = defaultValue, int c = defaultValue) 
{ 
    if (b == defaultValue) { b = a; } 
    if (c == defaultValue) { c = b; } 

    //... 
} 
+0

+1 Würde auch dies schreiben –

+0

Vielen Dank. Wenn ich mir die anderen Antworten anschaue, denke ich, dass Mike Seymours Ansatz noch besser ist. –

+2

Dies wird den Standardwert zur Laufzeit auflösen. Mikes Ansatz wird zur Kompilierzeit aufgelöst. Dies setzt auch voraus, dass der Typ (hier int) einen speziellen "Standard" -Flag-Wert hat (hier -999), und was Sie tun, ist gefährlich: Wenn irgendwie -999 als realer Wert übergeben wird, wird dies nicht wie erwartet funktionieren. .. – galinette

1

Ich glaube nicht, dass Sie das tun können, da das eine illegale Syntax ist. Konsultieren Sie jedoch den C99-Standard im PDF-Format (n1136.pdf).

Allerdings können Sie dies umgehen, indem static wie in Deklaration der Variablen statisch verwenden und sie in der Funktion f

 
static int global_a; 

/* In some other spot where you are calling f(), do this beforehand */ 
/* global_a = 4; f(); */ 

void f(void){ 
    int a = global_a; 
    b = c = a; 
    /* ..... */ 
} 

Ein großes Lob an Michael Burr mit meinem Fehler für den Hinweis auf! :)

Es klingt wie Sie müssen Ihren Code überdenken und ändern Sie es für so etwas.

Hoffen, dass dies hilft, Mit freundlichen Grüßen, Tom.

+0

Ich folge nicht - wenn Sie so etwas tun, gibt es keinen Grund, Parameter überhaupt zu übergeben, da sie nicht verwendet werden. –

+0

@Michael Burr: Ja du bist richtig ... mein Schlechter! Meh ... ich werde das entsprechend editieren und deine Eingabe erwähnen. Vielen Dank! :) – t0mm13b

1

Ihre erste Idee könnte so etwas wie dies zu tun:

void something(int a, int b=-1, int c=-1){ 
    if(b == -1) 
     b = a; 
    if(c == -1) 
     c = b; 
} 

I -1 verwendet, da diese Funktion nur mit positiven Werten. Aber was passiert, wenn jemand meine Klasse benutzt und einen Fehler macht, der schließlich die Methode -1 liefert? Es würde immer noch kompilieren und ausführen, aber das Ergebnis wäre für den Benutzer unvorhersehbar.So ist das intelligente, was zu tun wäre, jedes Standardargument zu entfernen und stattdessen eine Reihe von Methoden mit dem gleichen Namen wie diese machen:

void something(int a, int b, int c){ 
    /* Do something with a, b and c */ 
} 

void something(int a){ 
    something(a, a, a); 
} 

void something(int a, int b){ 
    something(a, b, b); 
} 

Es ist wirklich viel mehr Code nicht nehmen, und wenn jemand es verwendet In einer Programmierschnittstelle mit Funktionen zur automatischen Vervollständigung werden die 3 möglichen Prototypen angezeigt.

Verwandte Themen