2015-01-29 22 views
5

Chciałbym usprawnić kod, który ma około stu wyrażeń takich jak to:Czy jest możliwe przeciążenie funkcji w czasie wykonywania?

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

Gdzie AddData jest przeciążony jak

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

Chciałbym wyrazić powyższy kod tak :

AddData(key, flag? some_number : error_description); 

co, oczywiście, nie będzie kompilować, ponieważ wartość flaga jest określana w czasie rzeczywistym i AddData podpis musi być określona w czasie kompilacji .

Łącząc obie funkcje w coś jak

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

i rozwiązywania który z parametrów w użyciu, a która do ignorowania będzie działać, ale po prostu nie wygląda wystarczająco ładna.

W związku z tym pytanie: czy możliwe jest rozwiązanie problemu przeciążenia funkcji w czasie wykonywania w bardziej uzasadniony sposób?

+0

'AddData (? Klucz, flaga some_number: ERROR_DESCRIPTION) ; 'wygląda podobnie do' AddData (key, flag, some_number, error_description); '... – Jarod42

+1

Czy to ważne, że y jeden z 'someNumber' /' errorDescription' zostanie oceniony?Czy flaga ma inne wyrażenie dla każdego połączenia? – Deduplicator

+0

Można użyć wskaźników funkcji. Opierając się na danych wejściowych, usuń zaznaczenie odpowiedniego wskaźnika funkcji. –

Odpowiedz

0

Biorąc pod uwagę założenie, że żaden z tych symboli w wypowiedzi w pytaniu może być uwzględnione z najlepszym dostaniesz to

AddData(key, flag, some_number, error_description) 

Jeśli można to taki czynnik, który może flag odnosi się do wielu połączeń, możesz zacząć działać lepiej dzięki takiej konstrukcji, jak:

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

Tzn. "płynny" interfejs, który zapamiętuje która strona if jest wykonywana za każdym razem.

2

Wystarczy zdefiniować małego pomocnika w funkcji i użyć tego:

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

Jeśli flaga jest faktycznie zawsze taka sama, to prosta zmiana:

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

Zależą od kompilatora optymalizacja.

+0

+1 dla drugiej inkantacji (Założę się, że 'flaga' jest stała przez całe życie funkcji nadrzędnej). Jest wystarczająco krótki i ma właściwą intencję. –

1

Lepiej możesz użyć polimorfizmu zamiast setek ifs.

Zamiast flagi mają polimorficzną klasę bazową, która dodaje dane i zamiast zmieniać flagę, wybrałeś poprawną klasę pochodną.

kod wywołujący będzie wtedy po prostu być:

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

Przykład klasy bazowej i klas pochodnych:

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

Powiązane problemy