2016-10-30 7 views
1

Ich versuche, eine Funktion zu implementieren, die eine std::function nimmt, die ein It zurückgibt und eine beliebige Anzahl von Parametern erhalten kann.C++ 11 Funktionssignatur mit variadic Std :: Funktion

Ich habe Folgendes versucht, aber es kompiliert nicht und ich kann nicht verstehen, was der Fehler bedeutet.

template <typename ...Args> 
void ThrowOnError(std::function<int(Args...)> func, Args... args) 
{ 
    int err = func(args...); 
    if (err < 0) 
     throw std::exception(); 
} 

int f() 
{ 
    return 42; 
} 

int f(int x) 
{ 
    return x; 
} 


int main() 
{ 
    ThrowOnError(f); 
    ThrowOnError(f, 1); 
} 

Ich versuchte, die Templat-Funktion zu bewegen, um Header aber es hat nicht funktioniert, auch wenn ich die f(int x) Funktion kommentieren und nur mit nur f den Anruf verlassen, habe ich noch einen bekommen no matching overloaded function found und 'void ThrowOnError(std::function<int(Args...)>,Args...)': could not deduce template argument for 'std::function<int(Args...)>' from 'int (int)'

Was ist das Problem hier? Was fehlt mir in der Funktion?

P. - Ich möchte eine Antwort, die eine std::function, wenn möglich, und nicht einen weiteren Typnamen für den Funktor Typ.

Antwort

4

Sie stellen std::function nicht als Parameter zur Verfügung und Abzug kann nicht stattfinden.
In anderen, um die Funktion der std::function zuweisen, müssen Sie den tatsächlichen Typ kennen. Um es zu finden, muss Schluss sein. Damit der Abzug erfolgt, sollten Sie zuerst den Funktionszeiger dem std::function zuweisen, aber der Typ des Letzteren ist unbekannt (weil Abzug noch nicht stattgefunden hat).
Also in einer Schleife.

Darüber hinaus, wenn Sie dies tun:

ThrowOnError(f); 

Es ist unmöglich für den Compiler zu wissen, was f Sie verwenden möchten.
Sie sollten lieber etwas tun:

ThrowOnError(std::function<int()>{static_cast<int(*)()>(f)}); 

Oder diese (wenn Sie akzeptieren eine andere Template-Parameter für die Funktors verwenden):

ThrowOnError(static_cast<int(*)()>(f)); 

diese Weise können Sie die richtige Funktion Kommissionierung aus Die Überladung wird explizit gesetzt und der Compiler muss Ihre Absichten nicht erraten.
Wie bereits erwähnt, funktionieren würden, diese in Ordnung, wenn Sie auch die ThrowOnError Funktion ändern akzeptieren, wie es folgt:

template <typename F, typename ...Args> 
void ThrowOnError(F func, Args... args) 
{ 
    int err = func(args...); 
    if (err < 0) 
     throw std::exception(); 
} 

Oder noch besser:

template <typename F, typename ...Args> 
void ThrowOnError(F &&func, Args&&... args) 
{ 
    int err = std::forward<F>(func)(std::forward<Args>(args)...); 
    if (err < 0) 
     throw std::exception(); 
} 
+0

OK, aber dies mit einem nicht funktioniert 'typename F, typename ... Args 'auch. Wie kann es erreicht werden? – ZivS

+0

@ZivS Weitere Details hinzugefügt. – skypjack

+0

danke für die Antwort. In Bezug auf Ihre Bearbeitung: http://english.stackexchange.com/questions/1016/do-you-use-a-or-before-acronyms – ZivS

Verwandte Themen