2010-03-29 5 views
2

J'ai un code qui ressemble à:est back_insert_iterator <> sûr d'être passé par valeur?

struct Data { int value; }; 
class A { 
public: 
    typedef std::deque<boost::shared_ptr<Data> > TList; 
    std::back_insert_iterator<TList> GetInserter() 
    { 
     return std::back_inserter(m_List); 
    } 
private: 
    TList m_List; 
}; 
class AA { 
    boost::scoped_ptr<A> m_a; 
public: 
    AA() : m_a(new A()) {} 
    std::back_insert_iterator<A::TList> GetDataInserter() 
    { 
     return m_a->GetInserter(); 
    }   
}; 
class B { 
    template<class OutIt> 
    CopyInterestingDataTo(OutIt outIt) 
    { 
     // loop and check conditions for interesting data 
     // for every `it` in a Container<Data*> 
     // create a copy and store it 
     for(... it = ..; .. ; ..) if (...) { 
      *outIt = OutIt::container_type::value_type(new Data(**it)); 
      outIt++; // dummy 
     } 
    } 
    void func() 
    { 
     AA aa; 
     CopyInterestingDataTo(aa.GetDataInserter()); 
     // aa.m_a->m_List is empty! 
    } 
}; 

Le problème est que A::m_List est toujours vide même après CopyInterestingDataTo() est appelé. Cependant, si je débogue et passe à CopyInterestingDataTo(), l'itérateur stocke les données supposées insérées!

mise à jour: J'ai trouvé le coupable. J'ai en fait quelque chose comme:

class AA { 
    boost::scoped_ptr<A> m_a; 
    std::back_insert_iterator<A::TList> GetDataInserter() 
    { 
     //return m_a->GetInserter(); // wrong 
     return m_A->GetInserter(); // this is the one I actually want 
    }   
    // ..... somewhere at the end of the file 
    boost::scoped_ptr<A> m_A; 
}; 

Maintenant, quelle réponse dois-je marquer comme réponse? Vraiment désolé pour ceux qui ne sont pas choisis, mais vous avez certainement eu quelques votes up:)

+1

Peut-être qu'il est temps de réviser vos directives de style ... en gardant tous les champs ensemble aurait pu vous aider . J'en utilise un simple: la cohérence, toujours ajouter des membres où les autres membres sont. –

+0

@dribeas: et le cas de la lettre était également un problème. –

Répondre

4

La réponse courte est oui, back_insert_iterator est sûr de passer en valeur. La réponse longue: De la norme 24.4.2/3:

Les itérateurs d'insertion satisfont aux exigences des itérateurs de sortie.

Et 24.1.2/1

Une classe ou un haut-satisfait de type X Les exigences d'un itérateur de sortie si X est un type assignable (23,1) ...

Et enfin du tableau 64 23,1:

expressiont = u retour typeT& post-conditiont équivaut à u

EDIT: un coup d'oeil votre code semble OK pour me, êtes-vous certain à 100% que les éléments sont en train d'être inséré? Si vous êtes je voudrais faire un pas à travers le code et vérifier l'adresse de l'objet aa.m_a->m_List et le comparer à celui stocké dans outIt dans CopyInterestingDataTo, si elles ne sont pas la même chose est louche.

+0

Excellente info. Je m'attendais à ce que ce soit en sécurité. Maintenant, devrais-je changer ma question à "qu'est-ce qui ne va pas avec mon code?" au lieu? –

+0

Je ne pense pas. Votre question a été répondue, donc marquez la réponse acceptée et laissez la question telle quelle. Cela n'a pas résolu le problème que vous rencontrez, alors posez une autre question sur * ça *. (et s'il vous plaît, quelque chose de plus spécifique que "ce qui ne va pas avec mon code" :) – jalf

1

Le code suivant, qui compile, imprime « 1 », indiquant un élément ajouté à la liste:

#include <iostream> 
#include <deque> 
#include "boost/shared_ptr.hpp" 
#include "boost/scoped_ptr.hpp" 

struct Data { 
    int value; 
    Data(int n) : value(n) {} 
}; 

struct A { 
    typedef std::deque<boost::shared_ptr<Data> > TList; 
    std::back_insert_iterator<TList> GetInserter() 
    { 
     return std::back_inserter(m_List); 
    } 
    TList m_List; 
}; 

struct AA { 
    boost::scoped_ptr<A> m_a; 
    AA() : m_a(new A()) {} 
    std::back_insert_iterator<A::TList> GetDataInserter() 
    { 
     return m_a->GetInserter(); 
    }   
}; 

struct B { 
    template<class OutIt> 
    void CopyInterestingDataTo(OutIt outIt) 
    { 
     *outIt = typename OutIt::container_type::value_type(new Data(0)); 
     outIt++; // dummy 
    } 
    int func() 
    { 
     AA aa; 
     CopyInterestingDataTo(aa.GetDataInserter()); 
     return aa.m_a->m_List.size(); 
    } 
}; 

int main() { 
    B b; 
    int n = b.func();  
    std::cout << n << std::endl; 
} 
+0

maintenant, quelque chose est vraiment étrange avec mon code réel alors. : S –