2015-01-29 24 views
5

Ich möchte einen Code optimieren, die etwa hundert von Ausdrücken wie folgt hat:Kann eine Funktion zur Laufzeit überlastet werden?

if(flag) 
    AddData(key, some_number); 
else 
    AddData(key, error_description); 

Wo AddData ist überlastet als

bool AddData(int key, double value); 
bool AddData(int key, const char * error); 

ich so den oben stehenden Code zum Ausdruck bringen möchten :

AddData(key, flag? some_number : error_description); 

, die, natürlich, kompiliert nicht, weil der Wert des Kennzeichens zur Laufzeit und AddData Unterschrift muss bestimmt wird bei der Kompilierung bestimmt werden .

beide Funktionen in etwas Kombination wie

bool AddData(int key, bool flag, double value, const char * error); 

und Lösung, welche der Parameter zu verwenden und welche würden arbeiten zu ignorieren, aber es sieht einfach nicht schön genug.

Also die Frage: ist es möglich, die Funktionsüberlastung zur Laufzeit vernünftiger aufzulösen?

+0

'AddData (? Schlüssel, Flagge some_number: ERROR_DESCRIPTION) ; 'sieht ähnlich aus wie' AddData (key, flag, some_number, error_description); '... – Jarod42

+1

Ist es wichtig, dass onl y einer von 'someNumber' /' errorDescription' wird ausgewertet?Auch, ist die Flagge ein anderer Ausdruck für jeden Anruf? – Deduplicator

+0

Sie könnten Funktionszeiger verwenden. Basierend auf der Eingabe dereferenzieren Sie den entsprechenden Funktionszeiger. –

Antwort

0

eine Annahme gegeben, dass keines der Symbole im Ausdruck in Frage ausgeklammert, werden die am besten können Sie ist

AddData(key, flag, some_number, error_description) 

bekommen Wenn Sie es so Faktor kann, dass vielleicht flag auf mehrere Anrufe gilt, dann können Sie mit einer Struktur wie

Adder<flag>{} 
    .AddData(key1, val1, error1) 
    .AddData(key2, val2, error2) 
    .AddData(...) 
    . 
    . 

Ie besser beginnen. Ie eine "fließende" Schnittstelle, die daran erinnert, welche Seite der if jedes Mal genommen wird.

2

nur einen kleinen Helfer in der Funktion definieren, und verwenden Sie diese:

auto AddHelper = [](bool flag, int key, double value, const char* error) { 
    return flag ? AddData(key, value) : AddData(key, error); 
} 

Wenn das Flag eigentlich immer das gleiche ist, das ist eine einfache Änderung:

auto AddHelper = [flag](int key, double value, const char* error) { 
    return flag ? AddData(key, value) : AddData(key, error); 
} 

auf dem Compiler ab, für Optimierung.

+0

+1 für die zweite Beschwörung (Ich wette 'flag' ist über die Lebensdauer der Elternfunktion konstant). Es ist kurz genug und hat die richtige Absicht. –

1

Sie können besser Polymorphie statt Hunderte von ifs verwenden.

Anstelle eines Flags haben Sie eine polymorphe Basisklasse, die die Daten addiert, und statt das Flag zu ändern, wählen Sie die korrekte abgeleitete Klasse.

würde die Berufung Code sein dann einfach:

data_adder->add(key, value, error_description); 

Beispiel Basisklasse und abgeleitete Klassen:

struct DataAdder { 
    virtual void add(int key, double value, const char *error) = 0; 
protected: 
    ~DataAdder(){}; 
}; 

struct ValueDataAdder : DataAdder { 
    void add(int key, double value, const char*) override { AddData(key, value); } 
}; 

struct ErrorDataAdder : DataAdder { 
    void add(int key, double, const char* error) override { AddData(key, error); } 
}; 

Live demo

Verwandte Themen