Francesco
11/4/2008 10:12:00 AM
(2b|!2b)==? ha scritto:
> Francesco wrote:
> >
> > Bit Byter ha scritto:
> >
> >> I want to write a (singleton) container for instances of my class
> >> templates, however, I am not too sure on how to:
> >>
> >> 1). Store the instances
> >> 2). How to write the acccesor method (instance()) to retrieve an
> >> instance of particular template
> >> 3). What type to return an instance as ..
> >>
> >> Assuming I have the following code:
> >>
> >> class template
> >>
> >> template <class T1, class T2>
> >> class MyTree
> >> {
> >> T1 foo(const T2& a1);
> >> T2 foobar(const T1& a1, const T2& a2);
> >> };
> >>
> >>
> >> // Notes
> >> // Instance prototype not completed (see question 2 and 3)
> >> // Ideally, when an instance of a particular class is requested, if it
> >> dosen't yet exist, then an
> >> // instance is created and stored in the 'repository'
> >> class Container
> >> {
> >> instance();
> >> };
> >>
> >>
> >> //Main.cpp
> >>
> >> int main(int argc, char* argv[])
> >> {
> >> Container c;
> >>
> >> MyTree<double, int> * t1 = c.instance(/*some args here*/);
> >> MyTree<string, double> *t2 = c.instance(/*some args here*/);
> >>
> >> }
> >>
> >>
> >> Last but not the least, I want to be able to treat objects returned by
> >> the instance() method, in a generic way (i.e. in this example, I want
> >> to be able to treat them generically, as trees). Should I use
> >> inheritance (i.e. the class template inherits from a base Tree class)
> >> like this:
> >>
> >> template <class T1, class T2>
> >> class MyTree : public Tree
> >> {
> >> T1 foo(const T2& a1);
> >> T2 foobar(const T1& a1, const T2& a2);
> >> };
> >>
> >> or is there a better way?
> >
> > Hi,
> > I don't know exactly what you want to do, so there might be better
> > solutions...
> > But they way you've put it, I guess using something like boost::any
> > should do what
> > you want. Check the code below.
> > Hope it helps a little.
> > Bye,
> > Francesco
> >
> > #include <vector>
> >
> > #include <boost/any.hpp>
> > #include <boost/shared_ptr.hpp>
> > #include <boost/function.hpp>
> > #include <boost/bind.hpp>
> >
> > #include <iostream>
> >
> > using namespace boost;
> >
> > //------------------------------------------------------------
> >
> > class CObjBase
> > {
> > public:
> >
> > virtual ~CObjBase() {}
> >
> > virtual any DoSome( any const & ) = 0;
> >
> > virtual any DoOther( any const & inArg1,
> > any const & inArg2 ) = 0;
> >
> > virtual bool IsOfType( std::type_info const *,
> > std::type_info const * ) = 0;
> > };
> > //------------------------------------------------------------
> >
> > template< typename T1, typename T2 >
> > class CObjConcrete : public CObjBase
> > {
> > public:
> >
> > any DoSome( any const & inArg1 )
> > {
> > T2 obj = any_cast< T2 >( inArg1 ); // use object
> > std::cout << "-------\n";
> > std::cout << "Arg1: " << obj << std::endl;
> > return T1(); // return whatever;
> > }
> >
> > any DoOther( any const & inArg1, any const & inArg2 )
> > {
> > T1 obj1 = any_cast< T1 >( inArg1 );
> > T2 obj2 = any_cast< T2 >( inArg2 );
> > std::cout << "-------\n";
> > std::cout << "Arg1 : " << obj1 << std::endl;
> > std::cout << "Arg2 : " << obj2 << std::endl;
> > return obj2;
> > }
> >
> > bool IsOfType( std::type_info const * inT1Ptr,
> > std::type_info const * inT2Ptr )
> > {
> > if( *inT1Ptr == typeid( T1 ) and *inT2Ptr == typeid( T2 ) )
> > return true;
> > else
> > return false;
> > }
> > };
> >
> > //------------------------------------------------------------
> >
> > class CFactory
> > {
> > public:
> > static CFactory & GetInstance()
> > { static CFactory sObj; return sObj; }
> >
> > template< typename T1, typename T2 >
> > shared_ptr< CObjBase > Get();
> >
> > private:
> >
> > typedef std::vector< shared_ptr< CObjBase > > CRegister;
> >
> > CRegister mRegister;
> >
> > CFactory() {}
> > CFactory( CFactory const & );
> > ~CFactory() {}
> > CFactory & operator=( CFactory const & );
> > };
> >
> > CFactory & Factory() { return CFactory::GetInstance(); }
> >
> > //------------------------------------------------------------
> >
> > template< typename T1, typename T2 >
> > shared_ptr< CObjBase > CFactory::Get()
> > {
> >
> > CRegister::iterator iter = std::find_if(
> > mRegister.begin(),
> > mRegister.end(),
> > bind( &CObjBase::IsOfType, _1, &typeid( T1 ), &typeid( T2 ) )
> > );
> >
> > if( iter == mRegister.end() )
> > {
> > std::cout << "CREATING\n";
> > shared_ptr< CObjBase > ptr( new CObjConcrete< T1, T2 > );
> > mRegister.push_back( ptr );
> > return ptr;
> > }
> > else
> > {
> > std::cout << "REUSING\n";
> > return *iter;
> > }
> > }
> >
> > //------------------------------------------------------------
> >
> > int main()
> > {
> > Factory().Get< int, double >()->DoSome( 13.56 );
> > Factory().Get< std::string, int >()->DoOther(
> > std::string( "ola" ),
> > 100
> > );
> > Factory().Get< int, double >()->DoSome( 67.67 );
> > Factory().Get< std::string, int >()->DoOther(
> > std::string( "TEST" ),
> > 900
> > );
> > std::cin.get();
> > }
> >
> > //end code
>
> Thanks Francesco,
>
> This is exactly what I was looking for. I have a quick question about
> your IsOfType function:
>
> bool IsOfType( std::type_info const * inT1Ptr,
> std::type_info const * inT2Ptr )
> {
> if( *inT1Ptr == typeid( T1 ) and *inT2Ptr == typeid( T2 ) )
> return true;
> else
> return false;
> }
>
> You are using 'and' is that in the boost namespace? (I couldnt find it),
> or did you simply mean the unary boolean 'and' operator (&&) ?
No, it's not boost stuff, it's standard: just an alternative token to
&&. Check out the standard @ "2.5 Alternative Tokens"...
I believe it's a binary op though... ;-)
Glad I helped, bye,
Francesco