Results 1 to 4 of 4

Thread: specialization of a template method

  1. #1
    Join Date
    Jan 2007
    Posts
    68
    Thanks
    9
    Thanked 8 Times in 8 Posts

    Question specialization of a template method

    Hello,

    I'd like to specialize a method in a template class for another generic template class and can't figure out how to do it exactly.
    The simplified code looks like this:
    Qt Code:
    1. template<typename T>
    2. class ClassA
    3. {
    4. public:
    5. ClassA(){...}
    6. ~ClassA(void){...}
    7. ClassA(const ClassA<T> &other){...}
    8. ClassA<T>& operator=(const ClassA<T> &other){...}
    9.  
    10. inline T& operator() (int height, int width){
    11. if (height < 0 || height >= getHeight() || width < 0 || width >= getWidth())
    12. ...
    13. else
    14. return _pMat[height][width];
    15. }
    16.  
    17. inline T operator() (int height, int width) const{
    18. if (height < 0 || height >= getHeight() || width < 0 || width >= getWidth())
    19. ...
    20. else
    21. return _pMat[height][width];
    22. }
    23. inline int getWidth(void){return _iWidth;}
    24. inline int getWidth(void) const{return _iWidth;}
    25. inline int getHeight(void){return _iHeight;}
    26. inline int getHeight(void) const{return _iHeight;}
    27.  
    28. void print(void){
    29. std::cout << "print general" << std::endl;
    30. }
    31.  
    32. private:
    33. int _iWidth;
    34. int _iHeight;
    35. T** _pMat;
    36. };
    37.  
    38. template<>
    39. void ClassA< ClassB<int> >::print(void){
    40. std::cout << "print specialized <int>" << std::endl;
    41. }
    42.  
    43. template <typename U>
    44. class ClassB
    45. {
    46. public:
    47. inline ClassB(){...}
    48. inline ~ClassB(void){...}
    49. inline ClassB(const ClassB<U> &other){...}
    50. inline ClassB<U>& operator=(const ClassB<U> &other){...}
    51. inline U& operator() (int dimension){
    52. if (dimension >= 0 && dimension < getDimension())
    53. return _pData[dimension];
    54. else
    55. ...
    56. }
    57. inline U operator() (int dimension) const{
    58. if (dimension >= 0 && dimension < getDimension())
    59. return _pData[dimension];
    60. else
    61. ...
    62. }
    63. inline int getDimension(void) const{return _iDimension;}
    64. inline int getDimension(void){return _iDimension;}
    65. inline void print(void){...}
    66.  
    67. private:
    68. int _iDimension;
    69. U *_pData;
    70. };
    To copy to clipboard, switch view to plain text mode 

    if I instantiate the templates like this:
    Qt Code:
    1. ClassA< ClassB<int> > test;
    2. test.print();
    To copy to clipboard, switch view to plain text mode 
    everything works as desired and the specialized print method is called when ClassB is of type <int>.

    but I also need specialized methods for:
    Qt Code:
    1. ClassA< ClassB<double> > test1;
    2. ClassA< ClassB<float> > test2;
    3. //etc...
    To copy to clipboard, switch view to plain text mode 

    so I'd like to spezialize my print method like this:
    Qt Code:
    1. template<>
    2. void ClassA< ClassB<U> >::print(void){
    3. std::cout << "print specialized <U>" << std::endl;
    4. }
    To copy to clipboard, switch view to plain text mode 

    I hope this is possible, and I think I'm missing some template syntax to make it work.

    I hope someone knows how to do it...

    thanks in advance
    darksaga

  2. #2
    Join Date
    Jan 2008
    Location
    Warsaw, Poland
    Posts
    26
    Thanked 5 Times in 5 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows
    Wiki edits
    2

    Default Re: specialization of a template method

    AFAIK it's not possible. ClassA< ClassB<U> > is treated as completely different template, because ClassB<U> isn't fully specialized type.

    Let's see this in an example:
    Qt Code:
    1. #include<iostream>
    2.  
    3. using namespace std;
    4.  
    5. template <typename T>
    6. struct A {
    7. void func1() { cout << "general" << std::endl; }
    8. void func2() { cout << "hello" << std::endl; }
    9. };
    10.  
    11. template <typename T>
    12. struct B {};
    13.  
    14. // template <> // this line isn't necessary and helpful at all
    15. template <typename U>
    16. struct A< B<U> > {
    17. void func1() { cout << "specialized" << std::endl; }
    18. };
    19.  
    20. int main() {
    21. A< B<int> > a;
    22. a.func1();
    23. // a.func2(); // uncommented produces error: 'struct A<B<int> >' has no member named 'func2'
    24. return 0;
    25. }
    To copy to clipboard, switch view to plain text mode 

    What you can do?
    • Copy&paste code from ClassA to ClassA< B<T> > and change T to B<T> in it - maintainability will suffer from it.
    • Redesign your code to avoid "tricky" partial specialization.

  3. #3
    Join Date
    Jan 2007
    Posts
    68
    Thanks
    9
    Thanked 8 Times in 8 Posts

    Default Re: specialization of a template method

    is there any "empirical knowledge" how much the maintainability will suffer, doing it the way you suggested???

    my approach is to use:

    ClassA< int > var1; ClassA< float > var2; etc...
    for 1. dimensional data inside a grid, and

    ClassA< ClassB<int> > var1; ClassA< ClassB<float> > var2; etc...
    for x. dimensional data inside a grid.

    templating both, the grid & the data inside would make my code very generic & thats exacly what I want to achieve.

    regards

  4. #4
    Join Date
    Jan 2008
    Location
    Warsaw, Poland
    Posts
    26
    Thanked 5 Times in 5 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows
    Wiki edits
    2

    Default Re: specialization of a template method

    I said that maintainability will suffer, because if you have two (or even more) almost copies of the same code, you are obliged to (properly) propagate changes and that can be simply a source of troubles in future.

    There is a not-really-elegant way to achieve code duplication without using copy&paste by hand. You have to get unchangeable code between "specializations" from your class and put it in separate file. Now you can include it in your "specialized" templates. To deal with B<T>, use typedef. Below the idea is shown.

    template.cpp
    Qt Code:
    1. #include<iostream>
    2.  
    3. using namespace std;
    4.  
    5. template <typename T>
    6. class A {
    7. #include "template_.cpp"
    8. public:
    9. void func1() { cout << "general" << std::endl; }
    10. };
    11.  
    12. template <typename T>
    13. class B {};
    14.  
    15. template <typename U>
    16. class A< B<U> > {
    17. typedef B<U> T;
    18. #include "template_.cpp"
    19. public:
    20. void func1() { cout << "specialized" << std::endl; }
    21. };
    22.  
    23. int main() {
    24. A< B<int> > a;
    25. a.func1();
    26. a.func2();
    27. a.func3();
    28. return 0;
    29. }
    To copy to clipboard, switch view to plain text mode 

    template_.cpp
    Qt Code:
    1. public:
    2. void func2() { cout << "hello" << std::endl; }
    3. T* func3() { return t_; }
    4. private:
    5. T* t_;
    To copy to clipboard, switch view to plain text mode 

  5. The following user says thank you to przemoc for this useful post:

    darksaga (14th April 2008)

Similar Threads

  1. Template classes and abstraction of type
    By Raistlin in forum General Programming
    Replies: 15
    Last Post: 1st April 2008, 10:18
  2. Replies: 4
    Last Post: 10th March 2007, 18:01
  3. problem using template
    By mickey in forum General Programming
    Replies: 6
    Last Post: 18th November 2006, 15:57

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.