Une erreur commune. unary_function
et binary_function
ne sont que deux struct qui ajoutent typedefs
argument_type
result_type
et respectivement
first_argument_type
second_argument_type
result_type
Pas plus. Ils sont pour la commodité des créateurs de types d'objets de fonction, de sorte qu'ils n'ont pas à faire eux-mêmes. Mais ils ne se comportent pas polymorphique. Ce que vous voulez, c'est un wrapper d'objet fonction. boost::function
vient à l'esprit:
void foo(boost::function<void(const std::string&)> const& fct) {
const std::string str = "test";
fct(str); // no error anymore
}
Ou faire un modèle
template<typename FunctionObject>
void foo(FunctionObject const& fct) {
const std::string str = "test";
fct(str); // no error anymore
}
Vous pouvez le prendre par valeur, puis retourner la copie de foo
si l'utiliser pour l'appliquer à une certaine séquence. Ce qui permettrait à l'objet fonction de mettre à jour certaines variables d'état parmi ses membres. for_each
est un exemple qui le fait comme ça. Généralement, de toute façon, je les accepterais en valeur car ils sont généralement petits et les copier permet une plus grande flexibilité. Donc, je ne
template<typename FunctionObject>
void foo(FunctionObject fct) {
const std::string str = "test";
fct(str); // no error anymore
}
Vous serez alors en mesure de prendre une copie de fct et enregistrez quelque part, et l'opérateur de fct
() peut être non-const et mettre à jour certains membres (qui fait partie du point entier de operator()
). Souvenez-vous que si vous prenez un objet fonction par référence const, vous ne pouvez généralement pas le copier, car l'utilisateur aurait pu passer une fonction. La copier puis essaiera de déclarer localement une fonction au lieu d'un pointeur de fonction local. Cependant, l'acceptation de la valeur par défaut accepte un pointeur de fonction à la place d'une fonction qui peut être copiée en toute sécurité.
Merci pour votre réponse! La solution boost est-elle aussi efficace que la solution template? – Frank
la solution boost n'est pas aussi efficace, car elle doit faire un appel indirect à l'objet fonction enveloppé (elle crée sa propre vtable pour cela). Mais il a l'avantage de ne pas avoir besoin de modèle. vous pouvez simplement utiliser cette fonction boost.function et la stocker quelque part (par exemple en tant que membre de la classe). –
Je pense qu'il est le plus proche de ce que vous avez cherché avec unary_function –