2009-08-12 5 views
2

Wir verwenden einen Makro-Wrapper, um Where Parameter-Funktion zu binden.Fehler: Nicht-Lvalue in unären `& 'in C++

#define bindWhereClause(fieldName, fieldDataType, fieldData) _bindWhereClause(fieldName, fieldDataType, sizeof(fieldData), &fieldData) 

void _bindWhereClause(const char *name, int dataType, int dataSize, void *data) 
{ 
    // Implementation 
} 

Database.bindWhereClause("FIRST_NAME", SQL_VARCHAR, name.getFirstName()); 

Als ich versuchte, das Makro mit einer Funktion als Parameter (wie oben) erhalte ich die Fehlermeldung „Fehler: Nicht-L-Wert in einstelligen` & ‚“ zu nennen.

Ich kann den Makro mit normalen Variablen wie

Database.bindWhereClause("FIRST_NAME", SQL_VARCHAR, firstName); 

Wie Aufruf dieses Problem zu beheben? Muss ich Inline-Funktionen anstelle von Makros verwenden?

Schätzen Sie Ihre Hilfe im Voraus.

Danke, Mathew Liju

Antwort

3

Sie können die Adresse des Rückgabewerts einer Funktion nicht annehmen - sie ist ephemer.

Sie brauchen eine echte Variable verwenden:

Nametype first_name = name.getFirstName(); 
Database.bindWhereClause("FIRST_NAME", SQL_VARCHAR, first_name); 

// ... and maybe name.setFirstName(first_name); here 

eine Inline-Funktion verwenden würde es kompilieren, aber es ist unwahrscheinlich, dass tatsächlich Arbeit. Vermutlich wird dies wie von etwas gefolgt:

Database.execute(); 

..., die die Objekte, deren Adressen erwartet Sie früher bestanden nach wie vor gültig. Wenn Sie eine Inline-Funktion anstelle eines Makros verwenden, sind diese Objekte nicht mehr vorhanden, da sie nur lokal für die Inline-Funktion waren, die bereits beendet wurde.

+0

Ja Caf, ich führe die Abfrage im nächsten Schritt aus. Danke für den Vorschlag, den ich auf diese Weise umgesetzt habe. –

1

Für diesen Fall, dass Sie eine Inline-Funktion wird gut. Es ist im Allgemeinen viel besser und Sie sollten Inline-Funktionen verwenden, wenn die Verwendung von Makros absolut notwendig ist.

+0

Es ist jedoch unwahrscheinlich, dass in diesem besonderen Fall zu arbeiten. – caf

1

Das Makro expandiert nach:

_bindWhereClause("FIRST_NAME", SQL_VARCHAR, sizeof(name.getFirstName()), &name.getFirstName()) 

Sie nicht die Adresse des Rückgabewert einer Funktion übernehmen kann, so dass ungültig ist. Du kannst die Adresse einer Variablen oder eines Arguments nehmen, also würde es ja funktionieren.

+0

"Sie können die Adresse des Rückgabewertes einer Funktion nicht nehmen" Sie sind tatsächlich, wie in std ::: vector :: value_type & std :: vector operator (size_t), können Sie & my_vector [0] weil es gibt eine Referenz: ein l-Wert –

+0

... wie Sie my_vector [0] = "Hallo Welt" tun können, wenn Ihr Vektor Zeichenfolge enthält –

+0

Sie sind natürlich richtig. Ich konnte keine Möglichkeit finden, es genauer zu sagen, ohne von dem eigentlichen Punkt abzulenken, aber ich sprach ausdrücklich von einem zurückgegebenen * Wert * im Gegensatz zu einer zurückgegebenen * Referenz *. – Chuck