2010-08-01 6 views
0

J'essaye d'écrire une classe d'itérateur qui retourne une valeur de retour de la fonction getter quand elle est déréférencée. Le code fonctionne bien, mon seul problème est que je voudrais écrire member_ptr_functor en utilisant seulement un paramètre template et non 3, puisque je suis supposé pouvoir déduire les types de l'argument et renvoyer la valeur du type de fonction membre. Je pense que le problème est le type d'argument, j'ai essayé d'utiliser boost :: remove_ptr &, mais je ne pouvais pas le compiler.itération des getters d'un vecteur de pointeurs

#include <iostream> 
#include <vector> 
#include <boost/iterator/transform_iterator.hpp> 
#include <boost/iterator/indirect_iterator.hpp> 
using namespace boost; 
using namespace std; 

class CTest 
{ 
private: 
    int m_x; 

public: 
    CTest(int x) : m_x(x) 
    { 
    } 

    const int& GetX() const 
    { 
     return m_x; 
    } 

}; 

template<typename MemFunType, typename ArgumentType, typename ResultType> 
class member_ptr_functor : public unary_function<ArgumentType, ResultType> 
{ 
private: 
    MemFunType m_MemFun; 

public: 
    typedef ArgumentType argument_type; 
    typedef ResultType result_type; 

    member_ptr_functor(MemFunType MemFun) : m_MemFun(MemFun) 
    { 
    } 

    result_type operator() (argument_type arg) const 
    { 
     return m_MemFun(&arg); 
    } 
}; 

template<typename MemFunType, typename ArgumentType, typename ResultType> 
member_ptr_functor<MemFunType, ArgumentType, ResultType> make_member_ptr_functor(MemFunType MemFun) 
{ 
    return member_ptr_functor<MemFunType, ArgumentType, ResultType>(MemFun); 
} 

class CPrintFunctor : public unary_function<int, void> 
{ 
public: 
    void operator() (const int n) const 
    { 
     cout << n << endl; 
    } 
}; 

int main() 
{ 
    typedef vector<CTest> Container_t; 
    Container_t v; 
    v.push_back(CTest(1)); 

    CPrintFunctor PF; 
    Container_t::const_iterator itStart = v.begin(); 
    Container_t::const_iterator itEnd = v.end(); 

    typedef member_ptr_functor<const_mem_fun_t<const int&, CTest> , CTest, const int&> member_ptr_functor_t; 
    member_ptr_functor_t MemberPtrFunctor =  member_ptr_functor_t(mem_fun(&CTest::GetX)); 

    typedef transform_iterator<member_ptr_functor_t, Container_t::const_iterator, const int&, const int> transform_iterator_t; 
    transform_iterator_t itTransformStart = make_transform_iterator(itStart, MemberPtrFunctor); 
    transform_iterator_t itTransformEnd = make_transform_iterator(itEnd, MemberPtrFunctor); 

    for_each(itTransformStart, itTransformEnd, PF); 

    return 0; 
} 

Hagai.

Répondre

0

Ceci ne répond pas directement à votre question mais suggère plutôt une approche alternative.

Vous utilisez déjà Boost, alors pourquoi ne prenez-vous pas un peu plus loin, utilisez Boost.Range:

#include <boost/functional.hpp> 
#include <boost/range.hpp> 
#include <boost/range/algorithm/for_each.hpp> 
#include <boost/range/adaptor/transformed.hpp> 

// ... 

int main() 
{ 
    // ... 
    boost::range::for_each (
    boost::adaptors::transform (v, boost::mem_fun_ref (&CTest::GetX)), 
    PF); 
} 

Cela vous permet d'écrire la fonctionnalité que vous voulez sans avoir à définir et sans foncteurs propres en utilisant trop de typedefs.

+0

Merci pour la réponse. Je ne connais pas boost.range, et cela pourrait être une bonne solution à long terme. Cependant, le code que j'ai fourni n'est qu'un exemple, j'ai besoin de l'itérateur pour d'autres choses dans mon code. – barisdad

Questions connexes