Comment utiliser std :: transform avec des templates
-
05-07-2019 - |
Question
J'ai du mal à comprendre pourquoi je ne parviens pas à me transformer pour travailler avec une classe de modèles.
Voici une version simplifiée de la classe de modèle:
template<typename T>
class base
{
public :
base() : all_() {}
~base() {}
public:
bool add(T t)
{
typename vector<T>::iterator itr
= lower_bound(all_.begin(), all_.end(), t);
if ( itr == all_.end() || *itr != t )
{
all_.push_back(t);
cout << "ok" << endl;
return true;
}
cout << "failed" << endl;
return false;
}
static bool addTo(base<T> *c, T t)
{
return c->add(t);
}
private :
vector<T> all_;
};
Et c’est là que j’essaie d’utiliser transform pour capturer toutes les sorties de la fonction add member:
main()
{
base<int> test;
vector<bool> results;
vector<int> toAdd;
toAdd.push_back(10);
toAdd.push_back(11);
toAdd.push_back(10);
transform( toAdd.begin(), toAdd.end(),
back_inserter(results),
bind1st( (bool(*)(base<int>*,int))base<int>::addTo, &test ) );
}
Le but est d'insérer chaque membre du conteneur toAdd en utilisant soit :: base ou add :: base :: addTo, et de capturer les résultats bool dans les résultats vectoriels
La solution
Essayez:
transform( toAdd.begin(), toAdd.end(),
back_inserter(results),
bind1st( mem_fun(&base<int>::add), &test ) );
Le problème n'est pas le modèle, c'est que bind1st s'appuie sur un support supplémentaire pour fonctionner (voir http://www.sgi.com/tech/stl/AdaptableBinaryFunction.html ). Autant que je sache, il ne peut jamais fonctionner avec de simples indicateurs de fonction simples.
boost :: bind
peut faire plus de choses, si vous voulez l'apporter. Pour cette situation, vous n'en avez pas besoin, cependant: mem_fun
tourne un non -static member function en une fonction binaire adaptable. Par conséquent, addTo
n'est pas nécessaire non plus, mais si vous devez utiliser une fonction membre statique dans une situation similaire, il existe ptr_fun
.
Autres conseils
Ajoutez les éléments suivants à votre classe de base:
typedef base<T>* first_argument_type;
typedef T second_argument_type;
typedef bool result_type;
bool operator () (base<T> *c, T t) const {
return c->add(t);
}
et remplacez la transformation par:
transform(toAdd.begin(), toAdd.end(),
back_inserter(results), bind1st(base<int>(), &test ));