La notazione per la funzione std :: è piuttosto piacevole se confrontata con i puntatori di funzione. Tuttavia, a parte questo, non riesco a trovare un caso d'uso in cui non possa essere sostituito da puntatori. Quindi è solo zucchero sintattico per i puntatori di funzione?Esiste un caso d'uso per la funzione std :: che non è coperta dai puntatori di funzione, o è solo zucchero sintattico?
risposta
std::function<>
ti dà la possibilità di incapsulare qualsiasi tipo di oggetto callable, che è qualcosa di puntatori a funzione non possono farlo (anche se è vero che non catturare lambda possono essere convertiti per funzionare puntatori).
Per dare un'idea del tipo di flessibilità che consente di ottenere:
#include <functional>
#include <iostream>
#include <vector>
// A functor... (could even have state!)
struct X
{
void operator()() { std::cout << "Functor!" << std::endl; }
};
// A regular function...
void bar()
{
std::cout << "Function" << std::endl;
}
// A regular function with one argument that will be bound...
void foo(int x)
{
std::cout << "Bound Function " << x << "!" << std::endl;
}
int main()
{
// Heterogenous collection of callable objects
std::vector<std::function<void()>> functions;
// Fill in the container...
functions.push_back(X());
functions.push_back(bar);
functions.push_back(std::bind(foo, 42));
// And a add a lambda defined in-place as well...
functions.push_back([]() { std::cout << "Lambda!" << std::endl; });
// Now call them all!
for (auto& f : functions)
{
f(); // Same interface for all kinds of callable object...
}
}
Come al solito, vedere un live example here. Tra le altre cose, questo ti permette di realizzare lo Command Pattern.
Grazie mille, il tuo esempio ha molto senso. –
@static_rtti: OK, felice che abbia aiutato :) –
perché sei così poco entusiasta delle funzioni regolari? (è l'unico mancante '!') :-P –
std::function
è progettato per rappresentare qualsiasi tipo di oggetto callable. Ci sono molti oggetti chiamabili che non possono essere rappresentati in alcun modo da un puntatore a funzione.
un funtore:
struct foo { bool operator()(int x) { return x > 5; } }; bool (*f1)(int) = foo(); // Error std::function<bool(int)> f2 = foo(); // Okay
Non è possibile creare un'istanza di
foo
e conservarlo in un puntatore a funzione dibool(*)(int)
.Un lambda con una lambda-capture:
bool (*f1)(int) = [&](int x) { return x > y; }; // Error std::function<bool(int)> f2 = [&](int x) { return x > y; }; // Okay
Tuttavia, un lambda senza cattura può essere convertito in un puntatore alla funzione:
Il tipo di chiusura per un lambdacia- l'espressione senza lambda-capture ha una funzione di conversione const non-public pubblica non virtuale per puntare a una funzione che ha lo stesso parametro e tipi di ritorno dell'operatore di chiamata di funzione del tipo di chiusura. Il valore restituito da questa funzione di conversione deve essere l'indirizzo di una funzione che, invocata, ha lo stesso effetto del richiamo dell'operatore di chiamata di funzione del tipo di chiusura.
implementazione definita valori restituiti callable:
bool foo(int x, int y) { return x > y; }; bool (*f1)(int) = std::bind(&foo, std::placeholders::_1, 5); // Error (probably) std::function<bool(int)> f2 = std::bind(&foo, std::placeholders::_1, 5); // Okay
s'
std::bind
valore restituito è un oggetto richiamabile definito dall'implementazione. Solo come può essere usato quell'oggetto è specificato dallo standard, non dal suo tipo.
- 1. "sincrono" è davvero solo zucchero sintattico?
- 2. è l'operatore "è" solo zucchero sintattico per il metodo "IsInstanceOfType"
- 3. int.TryParse zucchero sintattico
- 4. Decoratori in pitone solo zucchero sintattico?
- 5. Esiste una funzione std che restituisce solo i suoi parametri?
- 6. Generico zucchero sintattico o vero miglioramento
- 7. rubino zucchero sintattico: si tratta di Nils
- 8. Le incomprensioni di Scala: caratteristica vitale o zucchero sintattico?
- 9. Scala Map: misterioso zucchero sintattico?
- 10. `std :: enable_if` è puntatore di funzione - come?
- 11. Intervista: puntatori a funzione vs caso interruttore
- 12. std :: mappa dei puntatori funzione membro?
- 13. La parola chiave 'yield' è uno zucchero sintattico? Qual è la sua implementazione
- 14. C++: è la funzione che ripresenta un comportamento non definito?
- 15. inizia con lo zucchero sintattico OCaml?
- 16. Sintassi zucchero per doppio generica funzione di
- 17. È possibile serializzare la funzione std ::?
- 18. Che caso è meglio?
- 19. Esistono "regole" per lo zucchero sintattico di Ruby?
- 20. Comprensioni elenco C# = puro zucchero sintattico?
- 21. Perché la funzione std :: function non è uguaglianza?
- 22. Esiste un tipo di funzione std :: o simile per lambda con parametro auto?
- 23. C++ 11 Funzione modello che utilizza una funzione std :: che dipende dai parametri del modello
- 24. zucchero sintattico try-catch in java
- 25. Matlab - Controllare se la funzione handle è una funzione particolare o un tipo di funzione
- 26. Puntatori funzione ed eredità
- 27. Perché la funzione << dell'operatore tra std :: ostream e char è una funzione non membro?
- 28. Stenografia per il ciclo - zucchero sintattico in C++ (11)
- 29. La funzione kill è sincrona?
- 30. Spiegazione dei puntatori a funzione
Qualsiasi oggetto callable che non è una funzione? Funtori dichiarati, lambda, espressioni vincolanti ...? –
std :: function è zucchero sintattico per tutti i tipi di funtori, non solo per i puntatori di funzione. – nurettin
@Xeo: le risposte in questa domanda sono molto meglio. –