CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 9 of 9
  1. #1
    Join Date
    Jan 2009
    Posts
    19

    [RESOLVED] template partial specialization

    Hello,
    I am trying to implement a dense and sparse matrix class using template specialization. The first two class method definitions work (one with no specialization, one with full specialization), but the third definition with partial specialization does not: if the commented region is uncommented, the example fails to compile.

    Code:
    #include <iostream>
    using std::cout;
    
    enum MatrixType{DENSE,SPARSE};
    
    template<class T,MatrixType MT>
    struct Matrix{ Matrix(); };
    
    template<class T, MatrixType MT>
    Matrix<T,MT>::Matrix<T,MT>(){
      cout << "default constructor\n";
    }
    
    template<>
    Matrix<double,DENSE>::Matrix<double,DENSE>(){
      cout << "<double,DENSE> constructor\n";
    }
    /*
    template<class T>
    Matrix<T,DENSE>::Matrix<T,DENSE>(){
      cout << "<T,DENSE> constructor\n";
    }
    */
    int main(){
      Matrix<double,SPARSE> V1;
      Matrix<int,DENSE> V2;
      Matrix<double,DENSE> V3;
      return 0;
    }
    One fix is to do full specializations of all needed types, but this requires a lot of code duplication. I suspect that this has to do with Matrix<T,DENSE> not being recognized as a valid class. Any ideas how to efficiently implement this, or something structurally similar?
    Last edited by jakevdp; January 1st, 2009 at 11:31 PM. Reason: added code tag

  2. #2
    Join Date
    Jan 2009
    Posts
    19

    Re: template partial specialization

    One more thing: I'm compiling with the gnu g++ compiler

  3. #3
    Join Date
    Apr 1999
    Posts
    27,449

    Re: template partial specialization

    Your code doesn't compile on Comeau C++, regardless of whether that code is commented out or not.
    Code:
    #include <iostream>
    using std::cout;
    
    enum MatrixType{DENSE,SPARSE};
    
    template<class T,MatrixType MT>
    struct Matrix{ Matrix(); };
    
    template<class T, MatrixType MT>
    Matrix<T,MT>::Matrix<T,MT>()
    {
      cout << "default constructor\n";
    }
    
    template<>
    Matrix<double,DENSE>::Matrix<double,DENSE>()
    {
      cout << "<double,DENSE> constructor\n";
    }
    
    /*
    template<class T>
    Matrix<T,DENSE>::Matrix<T,DENSE>(){
      cout << "<T,DENSE> constructor\n";
    }
    */
    int main(){
      Matrix<double,SPARSE> V1;
      Matrix<int,DENSE> V2;
      Matrix<double,DENSE> V3;
      return 0;
    }
    Code:
    Thank you for testing your code with Comeau C/C++!
    Tell others about http://www.comeaucomputing.com/tryitout !
    
    Your Comeau C/C++ test results are as follows:
    
    Comeau C/C++ 4.3.10.1 (Oct  6 2008 11:28:09) for ONLINE_EVALUATION_BETA2
    Copyright 1988-2008 Comeau Computing.  All rights reserved.
    MODE:strict errors C++ C++0x_extensions
    
    "ComeauTest.c", line 10: error: overloaded function "Matrix<T, MT>::Matrix" is not a template
      Matrix<T,MT>::Matrix<T,MT>()
                    ^
    
    "ComeauTest.c", line 16: error: overloaded function
              "Matrix<T, MT>::Matrix [with T=double, MT=DENSE]" is not a template
      Matrix<double,DENSE>::Matrix<double,DENSE>()
                            ^
    
    "ComeauTest.c", line 16: error: expected an identifier
      Matrix<double,DENSE>::Matrix<double,DENSE>()
                                                 ^
    
    3 errors detected in the compilation of "ComeauTest.c".
    
    In strict mode, with -tused, Compile failed
    What version of g++ are you compiling with? Always give the version of the compiler, as there can be vast differences in g++ between versions.

    Regards,

    Paul McKenzie

  4. #4
    Join Date
    Jan 2009
    Posts
    19

    Re: template partial specialization

    Quote Originally Posted by Paul McKenzie View Post
    What version of g++ are you compiling with?
    gcc version 3.4.5 on mingw

  5. #5
    Join Date
    Apr 1999
    Posts
    27,449

    Re: template partial specialization

    Quote Originally Posted by jakevdp View Post
    gcc version 3.4.5 on mingw
    Old.

    The latest version of g++ is (as far as I remember) 4.x.

    Not fixing the part where the code is commented, the following compiles correctly under Comeau:
    Code:
    #include <iostream>
    using std::cout;
    
    enum MatrixType{DENSE,SPARSE};
    
    template<class T,MatrixType MT>
    struct Matrix
    { 
        Matrix(); 
    };
    
    template<class T, MatrixType MT>
    Matrix<T,MT>::Matrix()
    {
      cout << "default constructor\n";
    }
    
    template<>
    Matrix<double,DENSE>::Matrix()
    {
      cout << "<double,DENSE> constructor\n";
    }
    
    int main(){
      Matrix<double,SPARSE> V1;
      Matrix<int,DENSE> V2;
      Matrix<double,DENSE> V3;
      return 0;
    }
    Regards,

    Paul McKenzie

  6. #6
    Join Date
    Apr 1999
    Posts
    27,449

    Re: template partial specialization

    Quote Originally Posted by jakevdp View Post
    One fix is to do full specializations of all needed types, but this requires a lot of code duplication.
    Do something similar to what you do in a non-template scenario -- factor out the common code, and place the code that is different in a class. Then you pass this "difference" class as one of the template arguments (this is called policy-based programming).

    Your generic Matrix code then uses the policy to determine how to do something at certain strategic points in the generic code.

    For an example, look how std::string works. The std::string is really a
    Code:
    basic_char<char, char_traits<char> >
    The bolded part of the template is the policy class.

    Regards,

    Paul McKenzie
    Last edited by Paul McKenzie; January 17th, 2009 at 04:18 AM.

  7. #7
    Join Date
    Apr 1999
    Posts
    27,449

    Re: template partial specialization

    So in general, you have a Matrix class, and the policy determines what to do with various types. Then you have no code duplication at all, since you have one generic function, which calls the policy class to do whatever customizations need to be done. You have "n" different policy classes, all custom.

    Of course, the policy class has to have the same public interface so that the generic function can "call" the customized code, but what goes in the policy's public interface is up to the policy -- the generic function doesn't care, as all it does is call the function.

    This is also called "compile-time polymorphism". Do a google search on policy-based programming, and you should see many articles on this.

    Regards,

    Paul McKenzie

  8. #8
    Join Date
    Jan 2009
    Posts
    19

    Re: template partial specialization

    Okay. I've compiled the following on g++ v4.1.2 :

    Code:
    #include <iostream>
    using std::cout;
    
    enum MatrixType{DENSE,SPARSE};
    
    template<class T,MatrixType MT>
    struct Matrix{ 
      Matrix(); 
    };
    
    template<class T, MatrixType MT>
    Matrix<T,MT>::Matrix(){
      cout << "default constructor\n";
    }
    
    template<>
    Matrix<double,DENSE>::Matrix(){
      cout << "<double,DENSE> constructor\n";
    }
    
    template<class T>
    Matrix<T,DENSE>::Matrix(){
      cout << "<T,DENSE> constructor\n";
    }
    
    int main(){
      Matrix<double,SPARSE> V1;
      Matrix<int,DENSE> V2;
      Matrix<double,DENSE> V3;
      return 0;
    }
    The third member definition produces the following errors:

    test.cpp:22: error: invalid use of undefined type 'struct Matrix<T, DENSE>'
    test.cpp:7: error: declaration of 'struct Matrix<T, DENSE>'
    test.cpp:22: error: template definition of non-template 'Matrix<T, DENSE>::Matrix()'

    So the partial specialization of Matrix is not being recognized as a valid class. Does anybody have ideas on how to make this partial specialization work?

  9. #9
    Join Date
    Jan 2009
    Posts
    19

    Re: template partial specialization

    Thanks Paul - I think you submitted your last post while I was writing mine

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured