Comment utiliser bind1st et bind2nd?
Je voudrais savoir comment utiliser les fonctions de liaison.
Voici l'idée:
J'ai cette fonction qui prend en paramètres:
void print_i(int t, std::string separator)
{
std::cout << t << separator;
}
Et je voudrais faire:
std::vector<int> elements;
//...
for_each(elements.begin(), elements.end(), std::bind2nd(print_i, '\n'));
Mais il ne fonctionne pas !
Voici ce que j'obtiens:
/usr/include/c++/4.3/backward/binders.h: In instantiation of ‘std::binder2nd<void ()(int, std::string)>’:
main.cpp:72: instantiated from here
/usr/include/c++/4.3/backward/binders.h:138: error: ‘void ()(int, std::string)’ is not a class, struct, or union type
/usr/include/c++/4.3/backward/binders.h:141: error: ‘void ()(int, std::string)’ is not a class, struct, or union type
/usr/include/c++/4.3/backward/binders.h:145: error: ‘void ()(int, std::string)’ is not a class, struct, or union type
/usr/include/c++/4.3/backward/binders.h:149: error: ‘void ()(int, std::string)’ is not a class, struct, or union type
/usr/include/c++/4.3/backward/binders.h:155: error: ‘void ()(int, std::string)’ is not a class, struct, or union type
/usr/include/c++/4.3/backward/binders.h:140: error: field ‘std::binder2nd<void ()(int, std::string)>::op’ invalidly declared function type
/usr/include/c++/4.3/backward/binders.h: In function ‘std::binder2nd<_Operation> std::bind2nd(const _Operation&, const _Tp&) [with _Operation = void ()(int, std::string), _Tp = char]’:
main.cpp:72: instantiated from here
/usr/include/c++/4.3/backward/binders.h:164: error: ‘void ()(int, std::string)’ is not a class, struct, or union type
/usr/include/c++/4.3/bits/stl_algo.h: In function ‘_Funct std::for_each(_IIter, _IIter, _Funct) [with _IIter = __gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >, _Funct = std::binder2nd<void ()(int, std::string)>]’:
main.cpp:72: instantiated from here
/usr/include/c++/4.3/bits/stl_algo.h:3791: error: no match for call to ‘(std::binder2nd<void ()(int, std::string)>) (int&)’
make: *** [all] Error 1
Je pourrais utiliser foncteur, mais il est plus rapide d'utiliser la liaison.
Merci!
Il n'est pas lié à la question, donc un petit commentaire à la place. La plus courte de code à la sortie d'une gamme est probablement le copiant dans
ostream_iterator
, par exemple std::copy(v.begin(), v.end(), std::ostream_iterator<int>(std::cout, "\n"));
.OriginalL'auteur Arthur | 2009-09-13
Vous devez vous connecter pour publier un commentaire.
L'argument de
bind2nd
doit être unAdaptableBinaryFunction
. Une simple fonction binaire ne remplit pas cette condition (adaptable en fonction typedefs pour son retour et les types d'argument, un simple type de fonction ne fournit pas toutes les typedefs). Vous pouvez utiliserstd::bind
qui est probablement le meilleur choix de toute façon.std::ptr_fun
pouvez convertir fonction binaire enAdaptableBinaryFunction
: sgi.com/tech/stl/ptr_fun.htmlOriginalL'auteur Rüdiger Hanke
Vous devez utiliser un Copiable/Refrencable objet, les ouvrages suivants:
Normalement, vous pouvez obtenir le même effet, simplement en procédant de la manière suivante:
Aussi en supposant que vous avez accès à TR1 dans la STL que vous utilisez, il est toujours mieux de réviser et remplacer les utilisations de bind1st et bind2nd avec std::bind
OriginalL'auteur
Vous devez faire les étapes suivantes:
1. créer une structure (ou de classe) qui hérite de std::binary_function
2. définir votre fonction de prédicat dans l'opérateur() la fonction de membre de la structure créée à l'étape 1
3. utilisation bind2nd pour lier une valeur appropriée de la structure créée à l'étape 1
J'ai fait tout cela dans un exemple. Vous pouvez lire l'article et télécharger le code complet sur le lien suivant: lier et de trouver
{}
, et avoir un bref explicatif exemple de code est toujours bon, commeclass A{public: bool operator()(const B& b){ doSomething(); return true;}
... juste un exemple 🙂OriginalL'auteur Waqqas Farooq
Ces fonctions sont obsolètes depuis C++11, et retiré en C++17. Comme mentionné dans un commentaire ci-dessus, la meilleure solution maintenant est d'utiliser
std::bind
et les espaces réservés:devient:
std::bind
variantes de toute façon, c'est une baisse-dans le remplacement.Personnellement, je trouve parfois
std::bind
plus lisible que les lambdas, selon le code environnant. Ce n'est qu'une préférence cependant, je suis d'accord à la fois, beau travail.OriginalL'auteur James Turner