template object as function parameter

Please support our C++ advertiser: Intel Parallel Studio Home
Thread Solved

Join Date: Jul 2008
Posts: 162
Reputation: Frederick2 has a spectacular aura about Frederick2 has a spectacular aura about Frederick2 has a spectacular aura about 
Solved Threads: 18
Frederick2 Frederick2 is offline Offline
Junior Poster

template object as function parameter

 
0
  #1
Dec 15th, 2008
I’m trying to learn how to use C++ templates, and I thought I was grasping it all ok until I decided to try to pass a template defined object variable as a function parameter. Having all kinds of troubles with that.

I’m using a typical example of a parameterizd array class. The members of the array are client objects with a name, gender, and age, i.e.,

  1. Fred m 56
  2. Sue f 46
  3. Mary f 21

Etc.

This class is CClient

  1. class CClient //CClients
  2. {
  3. public:
  4. CClient();
  5. ~CClient();
  6. void SetName(CString s);
  7. void SetGender(char gender);
  8. void SetAge(int iAge);
  9. void input();
  10. void display(unsigned int ctr) const;
  11.  
  12. private:
  13. CString m_Name;
  14. char m_Sex;
  15. int m_Age;
  16. };

My template is an array that should be able to hold some number of these, i.e.,

  1. template<class Tpl> class CArray
  2. {
  3. public:
  4. CArray();
  5. ~CArray();
  6.  
  7. bool AddNew(Tpl& pObj); //adds a new Tpl to Carray object
  8. unsigned int get_size() const; //returns actual number in CArray
  9. void dump(); //dumps objects to console
  10.  
  11. private:
  12. unsigned int m_New; //marks last/new object position
  13. Tpl x[MAX_SIZE]; //array of whatever
  14. };

Actually, I have this part working. If you take a look at the CClient class above you’ll see an input() member function declaration. I had implemented that with a scanf() to get series of names, genders, and ages from the keyboard. I was calling that from main(). That got pretty tiresome entering all that data by hand repeatedly just to test the workings of the classes and so forth, so I decided to try to add a non-member plain ordinary function called AddData() to my program called from main() that would blow several CClients into the CArray without my having to keypunch them. Only thing is, I wanted to declare a CClient object, and a CArray object in main(), and pass these objects as parameters to my AddData() function like so…

  1. Int main(void)
  2. {
  3. CArray<CClient> Folks;
  4. CClient c;
  5.  
  6. AddData(c, Folks);
  7. Folks.dump();
  8. getchar();
  9.  
  10. return 0;
  11. }

…and AddData() looks like this…

  1. template<class Tpl>
  2. void AddData(CClient& c, CArray<Tpl>& ar)
  3. {
  4. c.SetName("Fred"), c.SetGender('m'), c.SetAge(56), ar.AddNew(c);
  5. c.SetName("Elsie"), c.SetGender('f'), c.SetAge(55), ar.AddNew(c);
  6. c.SetName("Mark"), c.SetGender('m'), c.SetAge(60), ar.AddNew(c);
  7. c.SetName("Joanne"), c.SetGender('f'), c.SetAge(59), ar.AddNew(c);
  8. c.SetName("Alice"), c.SetGender('f'), c.SetAge(61), ar.AddNew(c);
  9. c.SetName("John"), c.SetGender('m'), c.SetAge(62); ar.AddNew(c);
  10. }

Here is the whole program, which works fine and produces the following output…

Output:
  1. CArray() Constructor Called!
  2.  
  3. 0 Fred m 56
  4. 1 Elsie f 55
  5. 2 Mark m 60
  6. 3 Joanne f 59
  7. 4 Alice f 61
  8. 5 John m 62
  9.  
  10. ~CArray() Destructor Called!

//Here Is The Working Program That Produces That Output
  1. //template6 //this program works – using VC++ 6
  2. #include <afx.h>
  3. #include <stdio.h>
  4. #define MAX_SIZE 10
  5.  
  6.  
  7. class CClient //CClients
  8. {
  9. public:
  10. CClient():m_Name("xxx"),m_Sex('x'),m_Age(0){/*puts("Constructor Called!");*/}
  11. ~CClient(){/*printf("Destructor Called!\n");*/}
  12. void SetName(CString s) {this->m_Name=s;}
  13. void SetGender(char gender) {this->m_Sex=gender;}
  14. void SetAge(int iAge) {this->m_Age=iAge;}
  15.  
  16. void input()
  17. {
  18. char name[20], gender[2];
  19. int age;
  20.  
  21. scanf("%s%s%d",name,gender,&age);
  22. this->m_Name=name;
  23. this->m_Sex=gender[0];
  24. this->m_Age=age;
  25. }
  26.  
  27. void display(unsigned int ctr) const
  28. {
  29. CString s;
  30. if(this)
  31. {
  32. s.Format("%u\t%-10s\t%c\t%d\n",ctr,m_Name,m_Sex,m_Age);
  33. printf("%s",s);
  34. }
  35. else
  36. {
  37. s.Format("%s\t%s\t%s\t%s\n","Null","Null","Null","Null");
  38. printf("%s",s);
  39. }
  40. }
  41.  
  42. private:
  43. CString m_Name;
  44. char m_Sex;
  45. int m_Age;
  46. };
  47.  
  48.  
  49. template<class Tpl> class CArray
  50. {
  51. public:
  52. CArray(){puts("CArray() Constructor Called!\n");this->m_New=0;}
  53. ~CArray(){puts("~CArray() Destructor Called!");}
  54.  
  55. bool AddNew(Tpl& pObj)
  56. {
  57. if(this->m_New<MAX_SIZE)
  58. {
  59. x[m_New]=pObj;
  60. this->m_New++;
  61. return true;
  62. }
  63.  
  64. return false;
  65. }
  66.  
  67. unsigned int get_size() const
  68. {
  69. return this->m_New;
  70. }
  71.  
  72. void dump()
  73. {
  74. unsigned int i;
  75. for(i=0;i<this->get_size();i++)
  76. x[i].display(i);
  77. }
  78.  
  79. private:
  80. unsigned int m_New;
  81. Tpl x[MAX_SIZE];
  82. };
  83.  
  84.  
  85. template<class Tpl>void AddData(CClient& c, CArray<Tpl>& ar)
  86. {
  87. c.SetName("Fred"), c.SetGender('m'), c.SetAge(56), ar.AddNew(c);
  88. c.SetName("Elsie"), c.SetGender('f'), c.SetAge(55), ar.AddNew(c);
  89. c.SetName("Mark"), c.SetGender('m'), c.SetAge(60), ar.AddNew(c);
  90. c.SetName("Joanne"), c.SetGender('f'), c.SetAge(59), ar.AddNew(c);
  91. c.SetName("Alice"), c.SetGender('f'), c.SetAge(61), ar.AddNew(c);
  92. c.SetName("John"), c.SetGender('m'), c.SetAge(62); ar.AddNew(c);
  93. }
  94.  
  95.  
  96. int main(void)
  97. {
  98. CArray<CClient> Folks;
  99. CClient c;
  100.  
  101. AddData(c, Folks);
  102. Folks.dump();
  103. getchar();
  104.  
  105. return 0;
  106. }

The problem with this is the MAX_SIZE #define at the top. That should really be the second parameter to the template, right? In other words, the template declaration should be this…

template<class Tpl, unsigned int iSize> class CArray //CArray

All my various C++ books show something like this in describing templates and making a generic array container class. The template declaration should contain the desired maximum size of the array of whatevers. However, I can no how and no way no matter what I do figure out how to modify this program to pass this CArray object to the AddData() function if I include that 2nd unsigned int iSize parameter as part of the template definition. I’ll post below the closest that I’ve been able to come to getting this to work. Here is the modified program with the added iSize parameter in the template…

  1. #include <afx.h> //template7
  2. #include <stdio.h>
  3. #define MAX_SIZE 10
  4.  
  5.  
  6. class CClient //CClients
  7. {
  8. public:
  9. CClient():m_Name("xxx"),m_Sex('x'),m_Age(0){/*puts("Constructor Called!\n");*/}
  10. ~CClient(){/*printf("Destructor Called!\n");*/}
  11. void SetName(CString s) {this->m_Name=s;}
  12. void SetGender(char gender) {this->m_Sex=gender;}
  13. void SetAge(int iAge) {this->m_Age=iAge;}
  14.  
  15. void input()
  16. {
  17. char name[20];
  18. char gender[2];
  19. int age;
  20.  
  21. scanf("%s%s%d",name,gender,&age);
  22. this->m_Name=name;
  23. this->m_Sex=gender[0];
  24. this->m_Age=age;
  25. }
  26.  
  27. void display(unsigned int ctr) const
  28. {
  29. CString s;
  30.  
  31. if(this)
  32. {
  33. s.Format("%u\t%-10s\t%c\t%d\n",ctr,m_Name,m_Sex,m_Age);
  34. printf("%s",s);
  35. }
  36. else
  37. {
  38. s.Format("%s\t%s\t%s\t%s\n","Null","Null","Null","Null");
  39. printf("%s",s);
  40. }
  41. }
  42.  
  43. private:
  44. CString m_Name;
  45. char m_Sex;
  46. int m_Age;
  47. };
  48.  
  49.  
  50. template<class Tpl, unsigned int iSize> class CArray //CArray
  51. {
  52. public:
  53. CArray() {puts("CArray() Constructor Called!\n");this->m_New=0;}
  54. ~CArray(){puts("~CArray() Destructor Called!");}
  55.  
  56. bool AddNew(Tpl& pObj)
  57. {
  58. if(this->m_New<iSize)
  59. {
  60. x[m_New]=pObj;
  61. this->m_New++;
  62. return true;
  63. }
  64.  
  65. return false;
  66. }
  67.  
  68. unsigned int get_size() const
  69. {
  70. return this->m_New;
  71. }
  72.  
  73. void dump()
  74. {
  75. unsigned int i;
  76. for(i=0;i<this->get_size();i++)
  77. x[i].display(i);
  78. }
  79.  
  80. private:
  81. unsigned int m_New;
  82. Tpl x[iSize];
  83. };
  84.  
  85.  
  86. template<class Tpl, unsigned int iSize>
  87. void AddData(CClient& c, CArray<Tpl,MAX_SIZE>& ar)
  88. {
  89. c.SetName("Fred"), c.SetGender('m'), c.SetAge(56), ar.AddNew(c);
  90. c.SetName("Elsie"), c.SetGender('f'), c.SetAge(55), ar.AddNew(c);
  91. c.SetName("Mark"), c.SetGender('m'), c.SetAge(60), ar.AddNew(c);
  92. c.SetName("Joanne"), c.SetGender('f'), c.SetAge(59), ar.AddNew(c);
  93. c.SetName("Alice"), c.SetGender('f'), c.SetAge(61), ar.AddNew(c);
  94. c.SetName("John"), c.SetGender('m'), c.SetAge(62); ar.AddNew(c);
  95. }
  96.  
  97.  
  98. int main(void)
  99. {
  100. CArray<CClient,MAX_SIZE> Folks;
  101. CClient c;
  102.  
  103. AddData(c, Folks);
  104. Folks.dump();
  105. getchar();
  106.  
  107. return 0;
  108. }
  109.  
  110. /* here is this particular error. As I vary stuff I get
  111.   all kinds of different errors
  112. Compiling...
  113. Main.cpp
  114. C:\CODE\VSTUDIO\VC++6\PROJECTS\Templates\template6\Main.cpp(103) : error C2783:
  115. 'void __cdecl AddData(class CClient &,class CArray<Tpl,10> &)' :
  116. could not deduce template argument for 'iSize'
  117. Error executing cl.exe.
  118.  
  119. Main.obj - 1 error(s), 0 warning(s)
  120. */

Could someone that knows what they are doing and understands templates show me how to do this? I’m sure its something stupid on my part, but I really don’t understand templates all that well yet. I find them confusing. I wanted to tackle Atl next, but figured I ought to have a pretty good grasp of templates before tackling that.
Reply With Quote Quick reply to this message  
Join Date: Sep 2004
Posts: 7,829
Reputation: Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute 
Solved Threads: 750
Team Colleague
Narue's Avatar
Narue Narue is offline Offline
Senior Bitch

Re: template object as function parameter

 
2
  #2
Dec 15th, 2008
>template<class Tpl, unsigned int iSize>
>void AddData(CClient& c, CArray<Tpl,MAX_SIZE>& ar)
Change MAX_SIZE to iSize. Since you didn't have iSize anywhere in the parameter list or as an explicit list in the instantiation, your compiler couldn't figure out what it was supposed to be.
New members chased away this month: 3
Reply With Quote Quick reply to this message  
Join Date: Jul 2008
Posts: 162
Reputation: Frederick2 has a spectacular aura about Frederick2 has a spectacular aura about Frederick2 has a spectacular aura about 
Solved Threads: 18
Frederick2 Frederick2 is offline Offline
Junior Poster

Re: template object as function parameter

 
0
  #3
Dec 16th, 2008
Thanks Narue! That did it. I really appreciate your taking the time to figure out my rather longish post. Now I have a few working examples of templates in use that I can study. I discovered I didn't understand the syntax for passing template classes as reference parameters when I attempted to do it.
Reply With Quote Quick reply to this message  
Reply

This thread has been marked solved.
Perhaps start a new thread instead?
Message:


Thread Tools Search this Thread



Tag cloud for C++
About Us | Contact Us | Advertise | DaniWeb | Acceptable Use Policy | RSS Feed

©2003 - 2009 DaniWeb® LLC