Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. Template Class Issues in C++.

Template Class Issues in C++.

Scheduled Pinned Locked Moved C / C++ / MFC
helpc++question
17 Posts 4 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • N Offline
    N Offline
    NeoAks007
    wrote on last edited by
    #1

    Hi all, I am developing a VC++ console application in which I have encountered a very strange problem. I have a class class A in which there are member objects of other different classes say class B and C. In Class A there is a member function search(int condition). This search() function depending upon argument returns a pointer to the member objects with the class. Code for this is:

    class B{
          // Class Definitions
    };
    class C{
          // Class Definitions
    };
    class A{
    public:
          B obj1;
          C obj2;
          someThing* search(int condition)  //What do I specify return type???
          {
                if(condition==1)
                      return &obj1;
                if(condition==2)
                      return &obj2;
                if(condition==3)
                      return this;
          }
    };
    

    Now the problem is that I am not able to specify any return type since it depends upon the condition which is known at runtime. I tried to introduce template as:

    template -typename type-
    type* search(int condition)
    {
          //Function Definition
    }
    

    But, doing so I cannot call the function from main() since, while calling I have to specify template parameter which again is dependent on condition at run-time. I am empty headed and clueless rite now about solving this weird situation.. :confused: Please suggest any problem solving approach. Also to mention that class structure is not to be changed.... HELP!!

    N 1 Reply Last reply
    0
    • N NeoAks007

      Hi all, I am developing a VC++ console application in which I have encountered a very strange problem. I have a class class A in which there are member objects of other different classes say class B and C. In Class A there is a member function search(int condition). This search() function depending upon argument returns a pointer to the member objects with the class. Code for this is:

      class B{
            // Class Definitions
      };
      class C{
            // Class Definitions
      };
      class A{
      public:
            B obj1;
            C obj2;
            someThing* search(int condition)  //What do I specify return type???
            {
                  if(condition==1)
                        return &obj1;
                  if(condition==2)
                        return &obj2;
                  if(condition==3)
                        return this;
            }
      };
      

      Now the problem is that I am not able to specify any return type since it depends upon the condition which is known at runtime. I tried to introduce template as:

      template -typename type-
      type* search(int condition)
      {
            //Function Definition
      }
      

      But, doing so I cannot call the function from main() since, while calling I have to specify template parameter which again is dependent on condition at run-time. I am empty headed and clueless rite now about solving this weird situation.. :confused: Please suggest any problem solving approach. Also to mention that class structure is not to be changed.... HELP!!

      N Offline
      N Offline
      N a v a n e e t h
      wrote on last edited by
      #2

      NeoAks007 wrote:

      Now the problem is that I am not able to specify any return type since it depends upon the condition which is known at runtime. I tried to introduce template as:

      You can't use templates here since your type is determined at run time. Create a abstract class and derive class B and C from it. You can return pointer to this abstract class instantiated with proper derived one. :)

      Navaneeth How to use google | Ask smart questions

      N 2 Replies Last reply
      0
      • N N a v a n e e t h

        NeoAks007 wrote:

        Now the problem is that I am not able to specify any return type since it depends upon the condition which is known at runtime. I tried to introduce template as:

        You can't use templates here since your type is determined at run time. Create a abstract class and derive class B and C from it. You can return pointer to this abstract class instantiated with proper derived one. :)

        Navaneeth How to use google | Ask smart questions

        N Offline
        N Offline
        NeoAks007
        wrote on last edited by
        #3

        Hmmmm.. That seems to be a nice and elegant solution... Let me try it before I thank you (since actual class hierarchies are quite complex so implementing this solution might introduce new errors) !!! :) ..

        N 1 Reply Last reply
        0
        • N NeoAks007

          Hmmmm.. That seems to be a nice and elegant solution... Let me try it before I thank you (since actual class hierarchies are quite complex so implementing this solution might introduce new errors) !!! :) ..

          N Offline
          N Offline
          N a v a n e e t h
          wrote on last edited by
          #4

          Good luck then. :)

          Navaneeth How to use google | Ask smart questions

          1 Reply Last reply
          0
          • N N a v a n e e t h

            NeoAks007 wrote:

            Now the problem is that I am not able to specify any return type since it depends upon the condition which is known at runtime. I tried to introduce template as:

            You can't use templates here since your type is determined at run time. Create a abstract class and derive class B and C from it. You can return pointer to this abstract class instantiated with proper derived one. :)

            Navaneeth How to use google | Ask smart questions

            N Offline
            N Offline
            NeoAks007
            wrote on last edited by
            #5

            N a v a n e e t h wrote:

            You can return pointer to this abstract class instantiated with proper derived one.

            Can you demonstrate how to do it? :confused:

            S N N 3 Replies Last reply
            0
            • N NeoAks007

              N a v a n e e t h wrote:

              You can return pointer to this abstract class instantiated with proper derived one.

              Can you demonstrate how to do it? :confused:

              S Offline
              S Offline
              Stuart Dootson
              wrote on last edited by
              #6

              class DummyBase {};

              class B : public DummyBase{
              // Class Definitions
              };
              class C : public DummyBase{
              // Class Definitions
              };

              class A{
              public:
              B obj1;
              C obj2;
              DummyBase* search(int condition) //What do I specify return type???
              {
              if(condition==1)
              return &obj1;
              if(condition==2)
              return &obj2;
              if(condition==3)
              return this;
              }
              };

              Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p

              1 Reply Last reply
              0
              • N NeoAks007

                N a v a n e e t h wrote:

                You can return pointer to this abstract class instantiated with proper derived one.

                Can you demonstrate how to do it? :confused:

                N Offline
                N Offline
                N a v a n e e t h
                wrote on last edited by
                #7

                Here is a trivial example.

                class Car{
                public:
                virtual string SayName() = 0;
                };

                class Mercedez : public Car{
                public:
                string SayName(){
                return "Mercedez";
                }
                };

                class Ferrari : public Car{
                public:
                string SayName(){
                return "Ferrari";
                }
                };

                Car* CreateACar(string carType){
                if(carType == "Mercedez")
                return new Mercedez;
                else if(carType == "Ferrari")
                return new Ferrari;
                }

                Use it like

                Car* car = CreateACar("Mercedez");
                std::cout << car->SayName();

                Read about factory design pattern. :)

                Navaneeth How to use google | Ask smart questions

                1 Reply Last reply
                0
                • N NeoAks007

                  N a v a n e e t h wrote:

                  You can return pointer to this abstract class instantiated with proper derived one.

                  Can you demonstrate how to do it? :confused:

                  N Offline
                  N Offline
                  NeoAks007
                  wrote on last edited by
                  #8

                  I had implemented DummyBase this way only. :) But there was problem accessing functions of class B & C through main() . After figuring out why, I have another serious problem now. Actual Implementations of class B and C are: class DummyBase {}; template <'class abc'> class Base{ public: abc func1(); }; class B : public Base`<datatype1`>, DummyBase{ // Class Definitions }; class C : public Base`<datatype2`>, DummyBase{ // Class Definitions }; class A: public Base`<datatype3`>, DummyBase{ public: B obj1; C obj2; DummyBase* search(int condition) //What do I specify return type??? { if(condition==1) return &obj1; if(condition==2) return &obj2; if(condition==3) return this; } }; void main() { DummyBase *ptr; A objA; int n; cin>>n; ptr = objA.search(n); ptr->func1(); //Error : Since DummyBase does not contain func1() }
                  Now the problem is that func1() cannot be included in DummyBase since return type of func1() is a template parameter. How to solve this..... :confused:

                  N S 2 Replies Last reply
                  0
                  • N NeoAks007

                    I had implemented DummyBase this way only. :) But there was problem accessing functions of class B & C through main() . After figuring out why, I have another serious problem now. Actual Implementations of class B and C are: class DummyBase {}; template <'class abc'> class Base{ public: abc func1(); }; class B : public Base`<datatype1`>, DummyBase{ // Class Definitions }; class C : public Base`<datatype2`>, DummyBase{ // Class Definitions }; class A: public Base`<datatype3`>, DummyBase{ public: B obj1; C obj2; DummyBase* search(int condition) //What do I specify return type??? { if(condition==1) return &obj1; if(condition==2) return &obj2; if(condition==3) return this; } }; void main() { DummyBase *ptr; A objA; int n; cin>>n; ptr = objA.search(n); ptr->func1(); //Error : Since DummyBase does not contain func1() }
                    Now the problem is that func1() cannot be included in DummyBase since return type of func1() is a template parameter. How to solve this..... :confused:

                    N Offline
                    N Offline
                    NeoAks007
                    wrote on last edited by
                    #9

                    Plz do reply posting solution to my problem (other than restructuring class Hierarchies). It quite urgent!!

                    1 Reply Last reply
                    0
                    • N NeoAks007

                      I had implemented DummyBase this way only. :) But there was problem accessing functions of class B & C through main() . After figuring out why, I have another serious problem now. Actual Implementations of class B and C are: class DummyBase {}; template <'class abc'> class Base{ public: abc func1(); }; class B : public Base`<datatype1`>, DummyBase{ // Class Definitions }; class C : public Base`<datatype2`>, DummyBase{ // Class Definitions }; class A: public Base`<datatype3`>, DummyBase{ public: B obj1; C obj2; DummyBase* search(int condition) //What do I specify return type??? { if(condition==1) return &obj1; if(condition==2) return &obj2; if(condition==3) return this; } }; void main() { DummyBase *ptr; A objA; int n; cin>>n; ptr = objA.search(n); ptr->func1(); //Error : Since DummyBase does not contain func1() }
                      Now the problem is that func1() cannot be included in DummyBase since return type of func1() is a template parameter. How to solve this..... :confused:

                      S Offline
                      S Offline
                      Stuart Dootson
                      wrote on last edited by
                      #10

                      That's a tricky one. I'd probably try it like this: Add virtual destructors to DummyBase, B and C, to ensure a v-table. Then you can use dynamic_cast to work out which typ has been returned:

                      class DummyBase { virtual ~DummyBase() {} };

                      template <'class abc'>
                      class Base{
                      public:
                      abc func1();
                      };

                      class B : public Base`<datatype1`>, DummyBase{
                      virtual ~B() {}
                      // Class Definitions
                      };
                      class C : public Base`<datatype2`>, DummyBase{
                      virtual ~C() {}
                      // Class Definitions
                      };

                      class A: public Base`<datatype3`>, DummyBase{
                      public:
                      B obj1;
                      C obj2;
                      DummyBase* search(int condition) //What do I specify return type???
                      {
                      if(condition==1)
                      return &obj1;
                      if(condition==2)
                      return &obj2;
                      if(condition==3)
                      return this;
                      }
                      };

                      void main()
                      {
                      DummyBase *ptr;
                      A objA;
                      int n;
                      cin>>n;
                      ptr = objA.search(n);
                      if (B* bPtr = dynamic_cast<B*>(ptr))
                      { bPtr->func1(); }
                      if (C* bPtr = dynamic_cast<C*>(ptr))
                      { bPtr->func1(); }
                      }

                      Yeah, it sucks because you're taking so many decisions. There are probably better ways, but I've not really put sufficient thought into it to think of a better one. Possibly something like Boost.Variant or Boost.Any might make things nicer.

                      Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p

                      N 1 Reply Last reply
                      0
                      • S Stuart Dootson

                        That's a tricky one. I'd probably try it like this: Add virtual destructors to DummyBase, B and C, to ensure a v-table. Then you can use dynamic_cast to work out which typ has been returned:

                        class DummyBase { virtual ~DummyBase() {} };

                        template <'class abc'>
                        class Base{
                        public:
                        abc func1();
                        };

                        class B : public Base`<datatype1`>, DummyBase{
                        virtual ~B() {}
                        // Class Definitions
                        };
                        class C : public Base`<datatype2`>, DummyBase{
                        virtual ~C() {}
                        // Class Definitions
                        };

                        class A: public Base`<datatype3`>, DummyBase{
                        public:
                        B obj1;
                        C obj2;
                        DummyBase* search(int condition) //What do I specify return type???
                        {
                        if(condition==1)
                        return &obj1;
                        if(condition==2)
                        return &obj2;
                        if(condition==3)
                        return this;
                        }
                        };

                        void main()
                        {
                        DummyBase *ptr;
                        A objA;
                        int n;
                        cin>>n;
                        ptr = objA.search(n);
                        if (B* bPtr = dynamic_cast<B*>(ptr))
                        { bPtr->func1(); }
                        if (C* bPtr = dynamic_cast<C*>(ptr))
                        { bPtr->func1(); }
                        }

                        Yeah, it sucks because you're taking so many decisions. There are probably better ways, but I've not really put sufficient thought into it to think of a better one. Possibly something like Boost.Variant or Boost.Any might make things nicer.

                        Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p

                        N Offline
                        N Offline
                        NeoAks007
                        wrote on last edited by
                        #11

                        Stuart Dootson wrote:

                        Yeah, it sucks because you're taking so many decisions.

                        Yes, that's a quite heck of a job. Actually search() function is like a framework function which links 2 separate applications. Now if this approach is to be implemented then I have to do a lot of coding at caller side. Also there are about 40-50 functions(may increase with further development) which would call search. And this approach is quite rigid and for instance if new class M object is introduced in class A a lot work would be required. So a more efficient flexible solution is required. :confused:

                        Stuart Dootson wrote:

                        But I've not really put sufficient thought into it to think of a better one.

                        If possible could you please spare some time to think of a better one??? ;P I have nearly wasted a day trying to find workarounds for it and now i cannot think more since here in India it's midnight now and i'm feeling sleepy. :zzz:

                        Stuart Dootson wrote:

                        Possibly something like Boost.Variant or Boost.Any might make things nicer.

                        I am not familiar with Boost libraries. So how could they be implemented??

                        S 1 Reply Last reply
                        0
                        • N NeoAks007

                          Stuart Dootson wrote:

                          Yeah, it sucks because you're taking so many decisions.

                          Yes, that's a quite heck of a job. Actually search() function is like a framework function which links 2 separate applications. Now if this approach is to be implemented then I have to do a lot of coding at caller side. Also there are about 40-50 functions(may increase with further development) which would call search. And this approach is quite rigid and for instance if new class M object is introduced in class A a lot work would be required. So a more efficient flexible solution is required. :confused:

                          Stuart Dootson wrote:

                          But I've not really put sufficient thought into it to think of a better one.

                          If possible could you please spare some time to think of a better one??? ;P I have nearly wasted a day trying to find workarounds for it and now i cannot think more since here in India it's midnight now and i'm feeling sleepy. :zzz:

                          Stuart Dootson wrote:

                          Possibly something like Boost.Variant or Boost.Any might make things nicer.

                          I am not familiar with Boost libraries. So how could they be implemented??

                          S Offline
                          S Offline
                          Stuart Dootson
                          wrote on last edited by
                          #12

                          With Boost, this is the best I can think of (note that I've substituted int, cahr, float for the template parameters):

                          #include <iostream>
                          #include <boost/variant.hpp>

                          template <class abc>
                          class Base{
                          public:
                          abc func1();
                          };

                          class B : public Base<int>{
                          public:
                          virtual ~B() {}
                          // Class Definitions
                          };
                          class C : public Base<float>{
                          public:
                          virtual ~C() {}
                          // Class Definitions
                          };

                          class A: public Base<char>{
                          public:
                          B obj1;
                          C obj2;
                          boost::variant<A*, B*, C*> search(int condition) //What do I specify return type???
                          {
                          if(condition==1)
                          return &obj1;
                          if(condition==2)
                          return &obj2;
                          if(condition==3)
                          return this;
                          }
                          };

                          int main(int, char**)
                          {
                          A objA;
                          int n;
                          std::cin>>n;
                          boost::variant<A*, B*, C*> v = objA.search(n);
                          if (B* b = boost::get<B*>(v))
                          {
                          b->func1();
                          }
                          else if (C* c = boost::get<C*>(v))
                          {
                          c->func1();
                          }
                          return 0;
                          }

                          Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p

                          N 1 Reply Last reply
                          0
                          • S Stuart Dootson

                            With Boost, this is the best I can think of (note that I've substituted int, cahr, float for the template parameters):

                            #include <iostream>
                            #include <boost/variant.hpp>

                            template <class abc>
                            class Base{
                            public:
                            abc func1();
                            };

                            class B : public Base<int>{
                            public:
                            virtual ~B() {}
                            // Class Definitions
                            };
                            class C : public Base<float>{
                            public:
                            virtual ~C() {}
                            // Class Definitions
                            };

                            class A: public Base<char>{
                            public:
                            B obj1;
                            C obj2;
                            boost::variant<A*, B*, C*> search(int condition) //What do I specify return type???
                            {
                            if(condition==1)
                            return &obj1;
                            if(condition==2)
                            return &obj2;
                            if(condition==3)
                            return this;
                            }
                            };

                            int main(int, char**)
                            {
                            A objA;
                            int n;
                            std::cin>>n;
                            boost::variant<A*, B*, C*> v = objA.search(n);
                            if (B* b = boost::get<B*>(v))
                            {
                            b->func1();
                            }
                            else if (C* c = boost::get<C*>(v))
                            {
                            c->func1();
                            }
                            return 0;
                            }

                            Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p

                            N Offline
                            N Offline
                            NeoAks007
                            wrote on last edited by
                            #13

                            Thanks for sparing some time.... :) But isn't this approach similar to previous approach??? Still I have to code a lot at caller side as in last solution... Is there no way to reduce coding at caller side??

                            S 1 Reply Last reply
                            0
                            • N NeoAks007

                              Thanks for sparing some time.... :) But isn't this approach similar to previous approach??? Still I have to code a lot at caller side as in last solution... Is there no way to reduce coding at caller side??

                              S Offline
                              S Offline
                              Stuart Dootson
                              wrote on last edited by
                              #14

                              NeoAks007 wrote:

                              Is there no way to reduce coding at caller side??

                              Not really - you have different return types for the different implementations of func1 - you have to handle those differently. If you want to handle them n the same way, then why not make them the same?

                              Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p

                              N 1 Reply Last reply
                              0
                              • S Stuart Dootson

                                NeoAks007 wrote:

                                Is there no way to reduce coding at caller side??

                                Not really - you have different return types for the different implementations of func1 - you have to handle those differently. If you want to handle them n the same way, then why not make them the same?

                                Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p

                                N Offline
                                N Offline
                                NeoAks007
                                wrote on last edited by
                                #15

                                Stuart Dootson wrote:

                                If you want to handle them n the same way, then why not make them the same?

                                It cannot be made same because their functionalities are different in different classes... I understand that this is holiday but still if anyone reading this thread comes up with an idea, do post a solution please... I need it seriously..... I am still listening.....

                                modified on Sunday, March 15, 2009 1:36 PM

                                J 1 Reply Last reply
                                0
                                • N NeoAks007

                                  Stuart Dootson wrote:

                                  If you want to handle them n the same way, then why not make them the same?

                                  It cannot be made same because their functionalities are different in different classes... I understand that this is holiday but still if anyone reading this thread comes up with an idea, do post a solution please... I need it seriously..... I am still listening.....

                                  modified on Sunday, March 15, 2009 1:36 PM

                                  J Offline
                                  J Offline
                                  Joe Woodbury
                                  wrote on last edited by
                                  #16

                                  I think you're making this way too complicated. If you change the return type, the code handling that will have to change as well.

                                  Anyone who thinks he has a better idea of what's good for people than people do is a swine. - P.J. O'Rourke

                                  N 1 Reply Last reply
                                  0
                                  • J Joe Woodbury

                                    I think you're making this way too complicated. If you change the return type, the code handling that will have to change as well.

                                    Anyone who thinks he has a better idea of what's good for people than people do is a swine. - P.J. O'Rourke

                                    N Offline
                                    N Offline
                                    NeoAks007
                                    wrote on last edited by
                                    #17

                                    In the End, I had to restructure all my class hierarchies and make the return type same for all functions. So, the problem is now solved!! :)

                                    1 Reply Last reply
                                    0
                                    Reply
                                    • Reply as topic
                                    Log in to reply
                                    • Oldest to Newest
                                    • Newest to Oldest
                                    • Most Votes


                                    • Login

                                    • Don't have an account? Register

                                    • Login or register to search.
                                    • First post
                                      Last post
                                    0
                                    • Categories
                                    • Recent
                                    • Tags
                                    • Popular
                                    • World
                                    • Users
                                    • Groups