Class templates and singleton container

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Bit Byter

    Class templates and singleton container

    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?
  • Francesco

    #2
    Re: Class templates and singleton container



    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::GetIn stance(); }

    //------------------------------------------------------------

    template< typename T1, typename T2 >
    shared_ptr< CObjBase CFactory::Get()
    {

    CRegister::iter ator iter = std::find_if(
    mRegister.begin (),
    mRegister.end() ,
    bind( &CObjBase::IsOf Type, _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

    Comment

    • (2b|!2b)==?

      #3
      Re: Class templates and singleton container

      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::GetIn stance(); }
      >
      //------------------------------------------------------------
      >
      template< typename T1, typename T2 >
      shared_ptr< CObjBase CFactory::Get()
      {
      >
      CRegister::iter ator iter = std::find_if(
      mRegister.begin (),
      mRegister.end() ,
      bind( &CObjBase::IsOf Type, _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 (&&) ?


      Comment

      • Francesco

        #4
        Re: Class templates and singleton container



        (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::GetIn stance(); }

        //------------------------------------------------------------

        template< typename T1, typename T2 >
        shared_ptr< CObjBase CFactory::Get()
        {

        CRegister::iter ator iter = std::find_if(
        mRegister.begin (),
        mRegister.end() ,
        bind( &CObjBase::IsOf Type, _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

        Comment

        • Francesco

          #5
          Re: Class templates and singleton container



          (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::GetIn stance(); }

          //------------------------------------------------------------

          template< typename T1, typename T2 >
          shared_ptr< CObjBase CFactory::Get()
          {

          CRegister::iter ator iter = std::find_if(
          mRegister.begin (),
          mRegister.end() ,
          bind( &CObjBase::IsOf Type, _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 (&&) ?
          [this might be a double post... sorry in advance]

          Anyway, no 'and' is not boost stuff, it's standard c++: it's 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

          Comment

          Working...