Speicher für verschiedenartige Methodenpointer



  • fantastisch, die ausgabe funktioniert prima.

    ich habe jetzt mal versucht das ganze auf eine eingabe zu adaptieren, leider funktioniert das ganze nicht so wie ich will.

    template <class ObjectType>
    class stream_to_methode : public boost::static_visitor<>
    {
    private:
        std::istream &is;
        const ObjectType &in_obj;
    
    public:
        stream_to_methode(std::istream &is, const ObjectType &in_obj) : is(is), in_obj(in_obj)
        {
    	}
    
        template <typename T>
        void operator()(void (ObjectType::*func)(T)) const
        {
    		T t;
    		is >> t;
    		(in_obj.*func)(t);
        }
    };
    

    und der aufruf

    template <class ObjectType>
    class MyDatenVector
    {
    //...
    void readDaten() const
        {
    		typedef std::vector<ObjectType>::const_iterator daten_citer;
            typedef std::map<string, variant_func>::const_iterator funcs_citer;
    
            daten_citer dit = daten.begin(), dend = daten.end();
            while(dit != dend)
            {
                const ObjectType &obj = *dit;
                std::cout << "Object " << &obj << "\n";
    
                funcs_citer fit = funcs.begin(), fend = funcs.end();
                while(fit !=  fend)
                {
                    const std::string &funcName = fit->first;
                    if(funcName.substr(0, 3) == "set")
                    {
                        std::cout << "\tMethod name = " << funcName << ", ";
    					std::cout << "input: ";
                        boost::apply_visitor(stream_to_methode<ObjectType>(std::cin, obj), fit->second);
                    }
                    ++fit;
                }
                ++dit;
            }
        }
    };
    

    vielleicht kannst du mir dazu nochmal einen tipp geben.

    vielen dank schon mal im voraus,
    sjoe



  • du hast fast alles richtig gemacht, weiter so!
    so würde ich es machen:

    template <class ObjectType> 
    class stream_to_methode : public boost::static_visitor<> 
    { 
    private: 
        std::istream &is; 
        /*!!!const*/ ObjectType &in_obj; 
    
    public: 
        stream_to_methode(std::istream &is, /*!!!const */ ObjectType &in_obj) : is(is), in_obj(in_obj) 
        { 
        } 
    
    	/*!!!*/
    	template<typename T> 
        void operator()(T obj) const 
        { 
            assert(0 && "is not setter!!!");         
        } 
    
        template <typename T> 
        void operator()(void (ObjectType::*func)(T))/*!!!const */
        { 
            T t; 
            is >> t; 
            (in_obj.*func)(t); 
        } 
    };
    

    der aufruf:

    void readDaten()/* !!! const */
        { 
    		/*!!!*/
            //typedef std::vector<ObjectType>::const_iterator daten_citer; 
    		typedef std::vector<ObjectType>::iterator daten_iter; 
    
            typedef std::map<string, variant_func>::const_iterator funcs_citer; 
    
            daten_iter dit = daten.begin(), dend = daten.end(); 
            while(dit != dend) 
            { 			
                /*!!!const */ObjectType &obj = *dit; 
                std::cout << "Object " << &obj << "\n"; 
    
                funcs_citer fit = funcs.begin(), fend = funcs.end(); 
                while(fit !=  fend) 
                { 
                    const std::string &funcName = fit->first; 
                    if(funcName.substr(0, 3) == "set") 
                    { 
                        std::cout << "\tMethod name = " << funcName << ", "; 
                        std::cout << "input: "; 
                        //!!!
                        boost::apply_visitor(stream_to_methode<ObjectType>(
    						std::cin, obj))(fit->second); 
                    } 
                    ++fit; 
                } 
                ++dit; 
            } 
        }
    

    Die Fehler hab ich mit "!!!" markiert.



  • hey,

    was heisst da explicit? was macht das genau?

    struct Print
        {
        public:
            explicit Print(std::ostream &os)
                :    os(os)
            {       
            }
    

    cu



  • hallo ssm,

    also dein code funktioniert eigentlich gut. unter ms visual studio 2005 express, leider benutze ich aber eclipse mit cdt und mingw, also gnu.
    dort will folgendes einfach nicht durch den compiler

    boost::apply_visitor(stream_to_methode<ObjectType>(std::cin, obj))(fit->second);
    // ...
    boost::apply_visitor(output_to_stream(std::cout, obj))(fit->second);
    

    ich habe es mal mit der ersatz konstruktion probiert

    boost::apply_visitor(stream_to_methode<ObjectType>(std::cin, obj), fit->second);
    // ...
    boost::apply_visitor(output_to_stream(std::cout, obj), fit->second);
    

    für output_to_stream funktioniert es, aber für stream_to_methode leider nicht (0 && "is not setter!!!").

    gibt es dafür ein workaround?

    mfg sjoe



  • -mingw Version?
    -BOOST Version
    -Fehlermeldung?



  • serbi schrieb:

    was heisst da explicit? was macht das genau?

    http://www.cppreference.com/keywords/explicit.html



  • -mingw Version?
    -BOOST Version
    -Fehlermeldung?

    schuldigung.

    for(map<string, variant_func>::iterator iter = getter.begin(); iter != getter.end(); iter++) {
        cout << iter->first << ": ";
        boost::apply_visitor(output_to_stream<ObjectType>(cout, DV.at(pos)))(iter->second); // hm
        cout << endl;
    }
    

    die dritte zeile wird angemeckert. und zwar mit folgendem:

    ../DataVectorCmd.h:97: could not convert `output_to_stream<Daten>((&std::cout), (+(this + 24)->std::vector<_Tp, _Alloc>::at(unsigned int) [with _Tp = Daten, _Alloc = std::allocator<Daten>](pos)))' to `output_to_stream<Daten>&'
    C:/Boost/include/boost-1_33_1/boost/variant/detail/apply_visitor_delayed.hpp:79: in passing argument 1 of `boost::apply_visitor_delayed_t<Visitor> boost::apply_visitor(Visitor&) [with Visitor = output_to_stream<Daten>]'
    

    mingw version 3.2.3
    boost version 1.33.1

    mfg sjoe



  • versuch mal so:

    const ObjectType &myObj = DV.at(pos);
    output_to_stream<ObjectType> myVisitor(std::cout, myObj);
    variant_func myFunc = iter->second;
    boost::apply_visitor(myVisitor, myFunc);
    


  • spuer, funktioniert.

    vielen dank,
    sjoe



  • When a constructor is specified as explicit, no automatic conversion will be used with that constructor --it will only be used when an initialization exactly matches a call to that constructor.

    was heisst das zu deutsch?



  • serbit schrieb:

    was heisst das zu deutsch?

    siehst du jetzt den Unterschied ?

    class A
    {
    public:
    	explicit A(const char *)
    	{
    	}
    };
    
    class B
    {
    public:
    	B(const char *)
    	{
    	}
    };
    
    void foo1(const A &a)
    {
    }
    
    void foo2(const B &b)
    {
    }
    
    int main() 
    { 	
    
    	//-------------------------------------------------------------------------
    	//error C2440: 'initializing' : cannot convert from 'const char [2]' to 'A'
    	//A a = "!";	
    
    	//OK!
    	B b = "!";
    	//-------------------------------------------------------------------------
    
    	//-------------------------------------------------------------------------
    	//OK!
    	A a1("!");
    
    	//OK!
    	B b1("!");
    	//-------------------------------------------------------------------------
    
    	//-------------------------------------------------------------------------
    	//error C2664: 'foo1' : cannot convert parameter 1 from 'const char [2]' to 'const A &'
    	//foo1("!");
    
    	//OK!
    	foo2("!");
    	//-------------------------------------------------------------------------
    }
    

Anmelden zum Antworten