2010-04-28 3 views
1

Je les types suivants:vecteur Copie des valeurs à vecteur des paires dans une ligne

struct X { int x; X(int val) : x(val) {} }; 
struct X2 { int x2; X2() : x2() {} }; 

typedef std::pair<X, X2>  pair_t; 
typedef std::vector<pair_t> pairs_vec_t; 
typedef std::vector<X>  X_vec_t; 

je dois initialiser instance de pairs_vec_t avec des valeurs de X_vec_t. J'utilise le code suivant et il fonctionne comme prévu:

int main() 
{ 
    pairs_vec_t ps; 
    X_vec_t xs; // this is not empty in the production code 

    ps.reserve(xs.size()); 

    { // I want to change this block to one line code. 
    struct get_pair { 
     pair_t operator()(const X& value) { 
     return std::make_pair(value, X2()); } 
    }; 
    std::transform(xs.begin(), xs.end(), back_inserter(ps), get_pair()); 
    } 

    return 0; 
} 

Ce que je suis en train de faire est de réduire mon bloc de copie à une ligne à l'utilisation boost::bind. Ce code ne fonctionne pas:

for_each(xs.begin(), xs.end(), boost::bind(&pairs_vec_t::push_back, ps, boost::bind(&std::make_pair, _1, X2()))); 

Je sais pourquoi il ne fonctionne pas , mais je veux savoir comment faire fonctionner sans déclarer des fonctions supplémentaires et struct?

+2

Nooo! Ce n'est pas Perl! Je préfère la version lisible :) –

+0

Je n'utiliserai pas 'bind' dans le code de production si le résultat final semble illisible. Honnêtement :) –

Répondre

5

quelque chose comme ça?

using boost::lambda; 
X2 x; 
transform(..., (bind(std::make_pair<X,X2>, _1, ref(x)))); 

Je ne peux pas vérifier pour le moment, mais si rappelé correctement de la mémoire, ce qui précède est valide.

+0

Merci, complètement oublié que 'make_pair' est une fonction de modèle. –

+1

@kirill longue soirée? :-) – Anycorn

3
std::for_each(xs.begin(), xs.end(), 
       boost::bind(&pairs_vec_t::push_back, &ps, 
// you need to pass a pointer —— at least for gcc. ^
          boost::bind(&std::make_pair<X,X2>, _1, X2()))); 
// you need to specify which make_pair to instantiate ^^^^^^ 
+0

Merci, complètement oublié que 'make_pair' est une fonction de modèle. –

0

Aucune amélioration nécessaire. std::bind2nd est désapprouvé en faveur de std::bind adopté de Boost, mais pour l'instant c'est la norme.

pairs_vec_t ps(xs.size()); 
transform(xs.begin(), xs.end(), ps.begin(), 
    bind2nd(ptr_fun(make_pair<X,X2>), X2())); 

Si vous faire ont Boost, il est plus efficace de insert une gamme (de transform_iterator) que itérer sur push_back ou pré-taille:

pairs_vec_t ps(
    make_transform_iterator(xs.begin(), bind2nd(ptr_fun(make_pair<X,X2>), X2())), 
    make_transform_iterator(xs.end(), bind2nd(ptr_fun(make_pair<X,X2>), X2()))); 

Comment est-ce pour un one-liner?

Questions connexes