Thread: Template Recursion Pickle

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    [...]indulge me with a [...] anything with int[...]
    O_o

    You have used 'T1' as part of an argument to the 'c' template in the specification of the specialization. No 'T1' symbol is in scope.

    You have not used 'T3' as part of an argument to the 'c' template in the specification of the specialization. You must use ever parameter as part of the specialization.

    Your example is wrong on two places. I'm not sure what you may have intended. I can't say if you understood or not.

    I'll write another example. (I'm writing inline so there may be a syntax bug.)

    Soma

    Code:
    #include <iostream>
    
    template
    <
       unsigned int a_F,
       unsigned int b_F,
       unsigned int c_F,
       unsigned int d_F,
       unsigned int e_F,
       unsigned int f_F,
       unsigned int g_F
    >
    struct tester
    {
    };
    
    template
    <
       typename type1_F,
       typename type2_F
    > // original template has two formal parameters
    struct test
    {
       test()
       {
          std::cout << "default" << '\n';
       }
    };
    
    template
    <
       typename type_F
    > // specialized template has one formal parameters
    // specialization "passes" two arguments to the original
    struct test<type_F, type_F>
    {
       test()
       {
          std::cout << "small specialization" << '\n';
       }
    };
    
    template
    <
       typename type_F,
       unsigned int a_F,
       unsigned int b_F,
       unsigned int c_F,
       unsigned int d_F,
       unsigned int e_F,
       unsigned int f_F,
       unsigned int g_F
    > // specialized template has eight formal parameters
    // specialization "passes" two arguments to the original
    struct test<type_F, tester<a_F, b_F, c_F, d_F, e_F, f_F, g_F> >
    {
       test()
       {
          std::cout << "big specialization" << '\n';
       }
    };
    
    int main()
    {
       typedef unsigned long whatever;
       typedef whatever * not_whatever;
       test<whatever, not_whatever> a;
       test<whatever, whatever> b;
       test<whatever, tester<0, 1, 2, 3, 4, 5, 6> > c;
       return(0);
    }

  2. #2
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    Yes and that's what [...] class definition or something.
    A few small source examples should correct your misunderstanding and explain the error you get.

    The key differences are [...] the template argument list.
    Yes. You have declared two overloads of the method named 'mgso': one with a 'cupper<?,?> &' parameter; the other with a 'cupper<1,?> &' parameter.

    So I think this device allows me to include the specialization right inside the class.
    You have not specialized anything. You have overloaded a template function with another template function. Now that both declarations exist you can define the functions inline, inside the class definition, or as you would normally.

    The key thing to take away from this: you are overloading functions. The rules still apply even though you are using class templates and template methods.

    Soma

    Code:
    // define struct A
    struct A
    {
    void test(int); //declare void A::test(int)
    };
    //define void A::test(int)
    void A::test(int){}
    Code:
    // define struct A
    struct A
    {
    void test(int); //declare void A::test(int)
    };
    //define void A::test(float)
    void A::test(float){} //error: there is no such function to define
    Code:
    // define struct A
    struct A
    {
    void test(int); //declare void A::test(int)
    };
    //define void B::test(int)
    void B::test(int){} //error: there is no such class and no such function to define
    Code:
    // define struct A
    struct A
    {
    void test(int); //declare void A::test(int)
    };
    //define void B::test(int)
    void B::test(float){} //error: again there is no such class and no such function to define
    Code:
    // here you have defined 'struct A' with the name 'matrix<?, ?, ?>'.
    template <int nrows, int ncols, int ld> class cmatrix
    {
    // here you have declared 'void A::test(int)' with the name 'void msgo(cupper<?,?>&)'
    template <int uld> inline void mgso( cupper<ncols,uld> &);
    };
    // here you have defined  'void A::test(int)' with the name 'void msgo(cupper<?,?>&)'
    template <int nrows, int ncols, int ld> template <int uld>
    inline void cmatrix<nrows,ncols,ld>::mgso( cupper<ncols,uld> &R){}
    Code:
    // now consider the problem source (with corrected syntax)
    template <int nrows, int ld> template <int uld>
    inline void cmatrix<nrows,0,ld>::mgso( cupper<0,uld> &R){}
    // the default template for 'cmatrix' doesn't have a declaration for such a function
    // the parameter of 'cupper<0,?> &' doesn't match the parameter 'cupper<?,?> &'
    // you've attempted to define a function of an enclosing class 'cmatrix<nrows,0,ld>'
    // that is an expansion of a partial specialization of a template
    // this is basically the same as the forth example above
    Last edited by phantomotap; 02-03-2009 at 07:31 PM.

  3. #3
    Registered User
    Join Date
    Apr 2007
    Posts
    141
    Quote Originally Posted by phantomotap View Post

    Code:
    // now consider the problem source (with corrected syntax)
    template <int nrows, int ld> template <int uld>
    inline void cmatrix<nrows,0,ld>::mgso( cupper<0,uld> &R){}
    // the default template for 'cmatrix' doesn't have a declaration for such a function
    // the parameter of 'cupper<0,?> &' doesn't match the parameter 'cupper<?,?> &'
    // you've attempted to define a function of an enclosing class 'cmatrix<nrows,0,ld>'
    // that is an expansion of a partial specialization of a template
    // this is basically the same as the forth example above
    Well there's the rub I suppose. The compiler can not infer that match, even though it may make sense to the programmer, since I can pick parameters for nrows, ncols and ld (the template parameters for cmatrix) that would enable such a match, namely ncols=0.

    Alll I can say is that I'd hate to have to write a C++ compiler. Moreover I can easily imagine why templated code is not very portable across differing compilers. By the way, after debugging, it does appear that my code is working as it should.

  4. #4
    3735928559
    Join Date
    Mar 2008
    Location
    RTP
    Posts
    838
    Quote Originally Posted by phantomotap View Post
    O_o

    You have used 'T1' as part of an argument to the 'c' template in the specification of the specialization. No 'T1' symbol is in scope.

    You have not used 'T3' as part of an argument to the 'c' template in the specification of the specialization. You must use ever parameter as part of the specialization.

    Your example is wrong on two places. I'm not sure what you may have intended. I can't say if you understood or not.

    I'll write another example. (I'm writing inline so there may be a syntax bug.)

    Soma

    Code:
    #include <iostream>
    
    template
    <
       unsigned int a_F,
       unsigned int b_F,
       unsigned int c_F,
       unsigned int d_F,
       unsigned int e_F,
       unsigned int f_F,
       unsigned int g_F
    >
    struct tester
    {
    };
    
    template
    <
       typename type1_F,
       typename type2_F
    > // original template has two formal parameters
    struct test
    {
       test()
       {
          std::cout << "default" << '\n';
       }
    };
    
    template
    <
       typename type_F
    > // specialized template has one formal parameters
    // specialization "passes" two arguments to the original
    struct test<type_F, type_F>
    {
       test()
       {
          std::cout << "small specialization" << '\n';
       }
    };
    
    template
    <
       typename type_F,
       unsigned int a_F,
       unsigned int b_F,
       unsigned int c_F,
       unsigned int d_F,
       unsigned int e_F,
       unsigned int f_F,
       unsigned int g_F
    > // specialized template has eight formal parameters
    // specialization "passes" two arguments to the original
    struct test<type_F, tester<a_F, b_F, c_F, d_F, e_F, f_F, g_F> >
    {
       test()
       {
          std::cout << "big specialization" << '\n';
       }
    };
    
    int main()
    {
       typedef unsigned long whatever;
       typedef whatever * not_whatever;
       test<whatever, not_whatever> a;
       test<whatever, whatever> b;
       test<whatever, tester<0, 1, 2, 3, 4, 5, 6> > c;
       return(0);
    }
    got it. yes, that is more or less the principle i was overly-succinctly trying to express.

    thanks.

  5. #5
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    that is more or less the principle i was overly-succinctly trying to express.
    Really?! O_o

    Sorry for the confusion.

    Soma

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Specialising a member function with a template template parameter
    By the4thamigo_uk in forum C++ Programming
    Replies: 10
    Last Post: 10-12-2007, 04:37 AM
  2. Screwy Linker Error - VC2005
    By Tonto in forum C++ Programming
    Replies: 5
    Last Post: 06-19-2007, 02:39 PM
  3. error: template with C linkage
    By michaels-r in forum C++ Programming
    Replies: 3
    Last Post: 05-17-2006, 08:11 AM
  4. Class Template Trouble
    By pliang in forum C++ Programming
    Replies: 4
    Last Post: 04-21-2005, 04:15 AM
  5. oh me oh my hash maps up the wazoo
    By DarkDays in forum C++ Programming
    Replies: 5
    Last Post: 11-30-2001, 12:54 PM