2015-08-05 10 views
10

Wie in der "möglichen Implementierung" von std::apply gezeigt, sehen wir, dass die Standardbibliotheksfunktion std::invoke verwendet wird, um das Callable-Objekt F aufzurufen.warum Aufruf Helper aufrufen und nicht einfach Funktor aufrufen?

Wird es in dieser Situation benötigt? Wenn ja, aus welchem ​​Grund?

Was sind die Vorteile des Schreibens:

template<typename F, typename ... Args> 
decltype(auto) func(F &&f, Args &&... args){ 
    return std::invoke(std::forward<F>(f), std::forward<Args>(args)...); 
} 

über:

template<typename F, typename ... Args> 
decltype(auto) func(F &&f, Args &&... args){ 
    return std::forward<F>(f)(std::forward<Args>(args)...); 
} 

?

Antwort

7

Ein Zeiger auf Mitglied ist Callable und invoke (oder INVOKE, wie soon-to-be-seven-bullet-point construct im Standard bekannt ist) 's Magie behandelt diesen Fall (na ja, vier und bald sechs Fällen tatsächlich), während der Funktionsaufruf Syntax nicht.

1

Ich möchte T.C.'s answer mit einem syntaktischen Beispiel ergänzen:

struct X { 
    int x; 
    int foo(int a) const { return a + x; } 
}; 

und Sie haben ein X Objekt und einen Zeiger auf eine Elementfunktion, z.B .:

X obj = X{1000}; 
auto fn = &X::foo; 

und brauchen func zu nennen.

  • Mit dem Aufruf-Syntax, wird dies nicht funktionieren:

    func_call(fn, obj, 24); // compiler error 
    

    error: must use '.' or '->' to call pointer-to-member function in [...]

    Stattdessen Sie um ihn zu arbeiten haben:

    func_call([obj, fn](int a) { return (obj.*fn)(a); }, 24); 
    
  • Wenn Sie die Methode invoke hatte , Sie hätten einfach schreiben können:

    func_invoke(fn, obj, 24); 
    
Verwandte Themen