Don't like ads? PRO users don't see any ads ;-)
Guest

Untitled

By: a guest on Jul 1st, 2012  |  syntax: None  |  size: 6.00 KB  |  hits: 12  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. C   specialization of template function inside template class
  2. template <class c1> class X {
  3. public:
  4.    template<typename returnT> returnT getAThing(std::string param);
  5.    static std::string getName();
  6. private:
  7.    c1 theData;
  8. };
  9.  
  10. // This works ok...
  11. template <class c1> std::string X<c1>::getName() {
  12.    return c1::getName();
  13. }
  14.  
  15. // This blows up with the error:
  16. // error: prototype for 'int X<c1>::getAThing(std::string)' does not match any in class 'X<c1>'
  17. template <class c1> template <typename returnT> int X<c1>::getAThing(std::string param) {
  18.    return getIntThing(param); // Some function that crunches on param and returns an int.
  19. }
  20.  
  21. // More specialized definitions of getAThing() for other types/classes go here...
  22.  
  23. class Y {
  24. public:
  25.    static std::string getName() { return "Y"; }
  26. };
  27.  
  28. int main(int argc, char* argv[])
  29. {
  30.    X<Y> tester;
  31.    int anIntThing = tester.getAThing<int>(std::string("param"));
  32.    cout << "Name: " <<  tester.getName() << endl;
  33.    cout << "An int thing: " << anIntThing << endl;
  34. }
  35.        
  36. #include <string>
  37. #include <iostream>
  38.  
  39. int getIntThing(const ::std::string &param);
  40.  
  41. template <typename returnT>
  42. returnT getThingFree(const ::std::string &param);
  43.  
  44. template <>
  45. int getThingFree<int>(const ::std::string &param)
  46. {
  47.    return getIntThing(param);
  48. }
  49.  
  50. // More specialized definitions of getAThing() for other types/classes
  51. // go here...
  52.  
  53. template <class c1> class X {
  54. public:
  55.    template<typename returnT> returnT getAThing(std::string param);
  56.    static std::string getName();
  57. private:
  58.    c1 theData;
  59. };
  60.  
  61. // This works ok...
  62. template <class c1> std::string X<c1>::getName() {
  63.    return c1::getName();
  64. }
  65.  
  66. // This also works, but it would be nice if I could explicitly specialize
  67. // this instead of having to explicitly specialize getThingFree.
  68. template <class c1>
  69. template <class RT>
  70. RT X<c1>::getAThing(std::string param) {
  71.    // Some function that crunches on param and returns an RT.
  72.    // Gosh, wouldn't it be nice if I didn't have to redirect through
  73.    // this free function?
  74.    return getThingFree<RT>(param);
  75. }
  76.  
  77. class Y {
  78. public:
  79.    static std::string getName() { return "Y"; }
  80. };
  81.  
  82. int main(int argc, char* argv[])
  83. {
  84.    using ::std::cout;
  85.    X<Y> tester;
  86.    int anIntThing = tester.getAThing<int>(std::string("param"));
  87.    cout << "Name: " <<  tester.getName() << 'n';
  88.    cout << "An int thing: " << anIntThing << 'n';
  89. }
  90.        
  91. #include <string>
  92. #include <iostream>
  93.  
  94. template <class c1> class X;
  95.  
  96. int getIntThing(const ::std::string &param)
  97. {
  98.    return param.size();
  99. }
  100.  
  101. // You can partially specialize this, but only for the class, or the
  102. // class and return type. You cannot partially specialize this for
  103. // just the return type. OTOH, specializations will be able to access
  104. // private or protected members of X<c1> as this class is declared a
  105. // friend.
  106. template <class c1>
  107. class friendlyGetThing {
  108.  public:
  109.    template <typename return_t>
  110.    static return_t getThing(X<c1> &xthis, const ::std::string &param,
  111.                             return_t *);
  112. };
  113.  
  114. // This can be partially specialized on either class, return type, or
  115. // both, but it cannot be declared a friend, so will have no access to
  116. // private or protected members of X<c1>.
  117. template <class c1, typename return_t>
  118. class getThingFunctor {
  119.  public:
  120.    typedef return_t r_t;
  121.  
  122.    return_t operator()(X<c1> &xthis, const ::std::string &param) {
  123.       return_t *fred = 0;
  124.       return friendlyGetThing<c1>::getThing(xthis, param, fred);
  125.    }
  126. };
  127.  
  128. template <class c1> class X {
  129. public:
  130.    friend class friendlyGetThing<c1>;
  131.  
  132.    template<typename returnT> returnT getAThing(std::string param) {
  133.       return getThingFunctor<c1, returnT>()(*this, param);
  134.    }
  135.    static std::string getName();
  136. private:
  137.    c1 theData;
  138. };
  139.  
  140. // This works ok...
  141. template <class c1> std::string X<c1>::getName() {
  142.    return c1::getName();
  143. }
  144.  
  145. class Y {
  146. public:
  147.    static std::string getName() { return "Y"; }
  148. };
  149.  
  150. template <class c1>
  151. class getThingFunctor<c1, int> {
  152.  public:
  153.    int operator()(X<c1> &xthis, const ::std::string &param) {
  154.       return getIntThing(param);
  155.    }
  156. };
  157.  
  158. // More specialized definitions of getAThingFunctor for other types/classes
  159. // go here...
  160.  
  161. int main(int argc, char* argv[])
  162. {
  163.    using ::std::cout;
  164.    X<Y> tester;
  165.    int anIntThing = tester.getAThing<int>(std::string("param"));
  166.    cout << "Name: " <<  tester.getName() << 'n';
  167.    cout << "An int thing: " << anIntThing << 'n';
  168. }
  169.        
  170. template <> template <> int X<Y>::getAThing<int>(std::string param) {
  171.    return getIntThing(param); // Some function that crunches on param and returns an int.
  172. }
  173.        
  174. template <>
  175. template <class T>
  176. int X<T>::template getAThing<int>(std::string param)
  177. {
  178.    return getIntThing(param);
  179. }
  180.        
  181. #include <iostream>
  182. #include <string>
  183.  
  184. using namespace std;
  185.  
  186. // IMPORTANT NOTE: AdaptingFunctor has no access to the guts of class X!
  187. // Thus, this solution is somewhat limited.
  188. template<typename t1> class AdaptingFunctor {
  189. public:
  190.    t1 operator() (string param);
  191. };
  192.  
  193. // Can specialize AdaptingFunctor for each type required:
  194. template<> int AdaptingFunctor<int>::operator() (string param)
  195. {
  196.    return param.size(); // <=== Insert required type-specific logic here
  197. }
  198.  
  199. // Additional specializations for each return type can go
  200. // here, without requiring specialization of class c1 for X...
  201.  
  202.  
  203. template <class c1> class X {
  204. public:
  205.    template<typename returnT>  returnT getAThing(std::string param)
  206.       {
  207.      AdaptingFunctor<returnT> adapter;
  208.      return adapter(param);
  209.       }
  210.    static std::string getName();
  211. private:
  212.    c1 theData;
  213. };
  214.  
  215. // Template definition of class method works ok...
  216. template <class c1> std::string X<c1>::getName() {
  217.    return c1::getName();
  218. }
  219.  
  220. class Y {
  221. public:
  222.    static std::string getName() { return "Y"; }
  223. };
  224.  
  225.  
  226. int main(int argc, char* argv[])
  227. {
  228.    X<Y> tester;
  229.    int anIntThing = tester.getAThing<int>(std::string("param"));
  230.    cout << "Name: " <<  tester.getName() << endl;
  231.    cout << "An int thing: " << anIntThing << endl;
  232. }
  233.        
  234. template <class T1>
  235. struct MyClass {
  236.   template <class T2>
  237.   void MyFunction();
  238. };
  239.  
  240. template <class T1>
  241. template <class T2>
  242. void MyClass<T1>::MyFunction() {  // NOTE:  NO T2 on this line.
  243.   // Code goes here
  244. }