help partial sepecialization

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • wakun@wakun.com

    #1

    help partial sepecialization

    Hi there,
    I am learning template programming. When testing the partial
    specialization, I have some probelms

    Here is a full templated class
    template <typename T, int n>
    class CT
    {
    public:
    T data[n][100][100];

    CT() {...}

    const T& get(int k, int i, int j)
    {
    return data[k][i][j];
    }
    };

    I have a partial specialization verion as follow

    template <typename T>
    class CT<T, 1>
    {
    public:
    T data[1][100][100];

    const T& get(int i, int j)
    {
    return data[0][i][j];
    }
    };

    In main, I have

    int main(void)
    {
    CT<double, 2> ct1;
    CT<double, 1> ct2;

    cout << ct1.get(1, 5, 8) << endl; // OK! return what I want
    cout << ct2.get(5, 8) << endl; // also OK
    cout << ct2.get(0, 5, 8) << endl; // ERROR !!!
    }

    I wonder how this error come ! Both ct1 and ct2 come from a same class
    except the different template parameter, why compiler complian no
    get(k, i, j) is defined in partial specialization class? If I want a
    partial specialization class with all members available, should I
    rewrite all the code ?

    Thanks in advance

  • puzzlecracker

    #2
    Re: help partial sepecialization


    wakun@wakun.com wrote:[color=blue]
    > Hi there,
    > I am learning template programming. When testing the partial
    > specialization, I have some probelms
    >
    > Here is a full templated class
    > template <typename T, int n>
    > class CT
    > {
    > public:
    > T data[n][100][100];
    >
    > CT() {...}
    >
    > const T& get(int k, int i, int j)
    > {
    > return data[k][i][j];
    > }
    > };
    >
    > I have a partial specialization verion as follow
    >
    > template <typename T>
    > class CT<T, 1>
    > {
    > public:
    > T data[1][100][100];
    >
    > const T& get(int i, int j)
    > {
    > return data[0][i][j];
    > }
    > };
    >
    > In main, I have
    >
    > int main(void)
    > {
    > CT<double, 2> ct1;
    > CT<double, 1> ct2;
    >
    > cout << ct1.get(1, 5, 8) << endl; // OK! return what I want
    > cout << ct2.get(5, 8) << endl; // also OK
    > cout << ct2.get(0, 5, 8) << endl; // ERROR !!!
    > }
    >
    > I wonder how this error come ! Both ct1 and ct2 come from a same class
    > except the different template parameter, why compiler complian no
    > get(k, i, j) is defined in partial specialization class? If I want a
    > partial specialization class with all members available, should I
    > rewrite all the code ?
    >
    > Thanks in advance[/color]

    They are different classes; in fact very different[color=blue]
    >cout << ct2.get(0, 5, 8) << endl; // ERROR !!![/color]
    you specialized class doesn't have an overload of this method that
    takes 3 params.
    look at faq for more clarification

    Comment

    • Jonathan Mcdougall

      #3
      Re: help partial sepecialization

      wakun@wakun.com wrote:[color=blue]
      > Hi there,
      > I am learning template programming. When testing the partial
      > specialization, I have some probelms
      > If I want a
      > partial specialization class with all members available, should I
      > rewrite all the code ?[/color]

      Yes.


      Jonathan

      Comment

      • wakun@wakun.com

        #4
        Re: help partial sepecialization


        Jonathan Mcdougall wrote:[color=blue]
        > wakun@wakun.com wrote:[color=green]
        > > Hi there,
        > > I am learning template programming. When testing the partial
        > > specialization, I have some probelms
        > > If I want a
        > > partial specialization class with all members available, should I
        > > rewrite all the code ?[/color]
        >
        > Yes.
        >[/color]
        OK. This time I consider inheritance

        template <typename T, int n>
        class Base
        {
        public:
        T data[n][100][100];

        Base() {...}

        void show(void)
        {
        cout << "Hi!" << endl;
        }

        const T& get(int k, int i, int j)
        {
        return data[k][i][j];
        }

        const T& get2(int k, int i, int j)
        {
        return data[k][i][j];
        }

        };

        template <typename T, int n>
        class CT : public Base<T, n>
        {
        public:
        CT() :Base<T, n> {...}
        };

        template <typename T>
        class CT<T, 1> : public Base<T, 1>
        {
        public:

        CT<T,1>() :Base<T, 1> {...}

        const T& get2(int i, int j)
        {
        return data[0][i][j];
        }

        };

        // main
        int main(void)
        {
        CT<double, 2> ct1;
        CT<double, 1> ct2;

        cout << ct1.get(1, 2, 3) << endl; // OK, of course
        cout << ct1.show() << endl; // OK, of course

        cout << ct2.show() << endl; // No problem, show is defined
        in Base
        cout << ct2.get(0, 1, 2) << endl; // OK. get is kept in both
        CT<double, n> and CT<double, 1>
        cout << ct2.get2(3, 2) << endl; // OK. overload function
        ctou << ct2.get2(0, 1, 2) << endl; // ERROR!!! No such function!?
        return 0;
        }

        Why compiler cannot find get2?

        Comment

        • Greg

          #5
          Re: help partial sepecialization

          wakun@wakun.com wrote:[color=blue]
          > Hi there,
          > I am learning template programming. When testing the partial
          > specialization, I have some probelms
          >
          > I wonder how this error come ! Both ct1 and ct2 come from a same class
          > except the different template parameter, why compiler complian no
          > get(k, i, j) is defined in partial specialization class? If I want a
          > partial specialization class with all members available, should I
          > rewrite all the code ?[/color]

          While you certainly have the partially-specialized class template be
          more-or-less a duplicate of the general class template, doing so
          creates a maintenance hassle, since the two class templates need to be
          maintained in parallel.

          A simpler approach is to declare the get method that accepts three
          parameters in the general template, but provide an implementation only
          in a full specialization:

          #include <iostream>

          using std::cout;
          using std::endl;

          template <class T, int N>
          class CT
          {
          public:
          T data[N][100][100];

          CT() {}

          const T& get(int k, int i, int j)
          {
          return data[k][i][j];
          }

          const T& get(int i, int j); // not implemented here
          };

          template <>
          const double& CT<double, 1>::get(int i, int j)
          {
          return data[0][i][j];
          }

          int main()
          {
          CT<double, 2> ct1;
          CT<double, 1> ct2;

          cout << ct1.get(1, 5, 8) << endl; // OK! return what I want
          cout << ct2.get(5, 8) << endl; // also OK
          cout << ct2.get(0, 5, 8) << endl; // OK
          }

          Greg

          Comment

          Working...