Class template specialization

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • (2b|!2b)==?

    Class template specialization

    I have a class template. Each of the instantiations implements a method
    in the class template differently, so I (need?) to use template
    speciaization.

    My question is this, when writing the specialization, do I need to
    implement only the method that is 'different', or do I need to implement
    all the methods in the class template?


    template <typename T1, typename T2>
    class MyClass
    {
    void foo(const T1&, T2&) const;
    ...
    //other methods follow below
    int foobar(T1, T1, T2&);
    // ...etc
    };

    template<>
    class MyClass<int,dou ble>
    {
    void foo(const int& i, double& d) const
    {
    //'specialized' logic here
    }

    /* Do I need all the other methods here ?
    .... */
    };
  • Salt_Peter

    #2
    Re: Class template specialization

    On Nov 3, 7:22 pm, "(2b|!2b)== ?" <void-s...@ursa-major.comwrote:
    I have a class template. Each of the instantiations implements a method
    in the class template differently, so I (need?) to use template
    speciaization.
    >
    My question is this, when writing the specialization, do I need to
    implement only the method that is 'different', or do I need to implement
    all the methods in the class template?
    >
    template <typename T1, typename T2>
    class MyClass
    {
    public:
       void foo(const T1&, T2&) const;
       ...
       //other methods follow below
       int foobar(T1, T1, T2&);
       // ...etc
    >
    };
    >
    template<>
    class MyClass<int,dou ble>
    {
    public:
         void foo(const int& i, double& d) const
         {
            //'specialized' logic here
         }
    >
        /* Do I need all the other methods here ?
         .... */
    >
    >
    >
    };
    Yes, You'll need to provide specialization for the entire type.
    To partially specialize a template, derive from the generic one:

    class DerivedClass : public MyClass< int, double >
    {
    public:
    void foo(const int& i, double& d) const
    {
    // do specialized stuff here
    }
    };

    foo(...) now overides any foo(...) in the base class and foobar() is
    available.
    This works too:

    template< typename N = int, typename D = double >
    class DerivedClass : public MyClass< N, D >
    {
    public:
    void foo(const N& i, D& d) const
    {
    std::cout << "DerivedClass:: foo(const int&, double&) const\n";
    }
    };

    DerivedClass< instance;
    instance.foobar (...);

    Comment

    • Triple-DES

      #3
      Re: Class template specialization

      On 4 Nov, 01:22, "(2b|!2b)== ?" <void-s...@ursa-major.comwrote:
      I have a class template. Each of the instantiations implements a method
      in the class template differently, so I (need?) to use template
      speciaization.
      >
      My question is this, when writing the specialization, do I need to
      implement only the method that is 'different', or do I need to implement
      all the methods in the class template?
      >
      template <typename T1, typename T2>
      class MyClass
      {
         void foo(const T1&, T2&) const;
         ...
         //other methods follow below
         int foobar(T1, T1, T2&);
         // ...etc
      >
      };
      If only the function body is different, you could simply do this:

      template<>
      void MyClass<int, double>::foo(co nst int&, double&) const
      {
      // ...
      }
      template<>
      void MyClass<double, double>::foo(co nst double&, double&) const
      {
      // ...
      }

      Comment

      • Hendrik Schober

        #4
        Re: Class template specialization

        Triple-DES wrote:
        On 4 Nov, 01:22, "(2b|!2b)== ?" <void-s...@ursa-major.comwrote:
        >I have a class template. Each of the instantiations implements a method
        >in the class template differently, so I (need?) to use template
        >speciaizatio n.
        >>
        >My question is this, when writing the specialization, do I need to
        >implement only the method that is 'different', or do I need to implement
        >all the methods in the class template?
        >>
        >template <typename T1, typename T2>
        >class MyClass
        >{
        > void foo(const T1&, T2&) const;
        > ...
        > //other methods follow below
        > int foobar(T1, T1, T2&);
        > // ...etc
        >>
        >};
        >
        If only the function body is different, you could simply do this:
        >
        template<>
        void MyClass<int, double>::foo(co nst int&, double&) const
        {
        // ...
        }
        template<>
        void MyClass<double, double>::foo(co nst double&, double&) const
        {
        // ...
        }
        That would be explicit instantiation, or what's that called
        officially?

        Schobi

        Comment

        • Andrey Tarasevich

          #5
          Re: Class template specialization

          Hendrik Schober wrote:
          >>template <typename T1, typename T2>
          >>class MyClass
          >>{
          >> void foo(const T1&, T2&) const;
          >> ...
          >> //other methods follow below
          >> int foobar(T1, T1, T2&);
          >> // ...etc
          >>>
          >>};
          >>
          >If only the function body is different, you could simply do this:
          >>
          >template<>
          >void MyClass<int, double>::foo(co nst int&, double&) const
          >{
          > // ...
          >}
          >template<>
          >void MyClass<double, double>::foo(co nst double&, double&) const
          >{
          > // ...
          >}
          >
          That would be explicit instantiation, or what's that called
          officially?
          >
          That's called "explicit specialization" (the 'template<>' bit is usually
          a dead giveaway). When it comes to explicit specialization, the class
          itself and the members of the class are pretty much independent
          templates. You can perform explicit specialization on them
          independently. You can explicitly specialize the entire class template
          (meaning that you'll have to redefine the whole thing from scratch), or
          you can explicitly specialize the members (without specializing the
          entire class). The latter is what's done in the above code.

          Of course, once you decided to explicitly specialize the entire class
          template for type 'T', you can no longer explicitly specialize just the
          members for the same type 'T'.

          --
          Best regards,
          Andrey Tarasevich

          Comment

          • Hendrik Schober

            #6
            Re: Class template specialization

            Andrey Tarasevich wrote:
            Hendrik Schober wrote:
            >>>template <typename T1, typename T2>
            >>>class MyClass
            >>>{
            >>> void foo(const T1&, T2&) const;
            >>> ...
            >>> //other methods follow below
            >>> int foobar(T1, T1, T2&);
            >>> // ...etc
            >>>>
            >>>};
            >>If only the function body is different, you could simply do this:
            >>>
            >>template<>
            >>void MyClass<int, double>::foo(co nst int&, double&) const
            >>{
            >> // ...
            >>}
            >>template<>
            >>void MyClass<double, double>::foo(co nst double&, double&) const
            >>{
            >> // ...
            >>}
            > That would be explicit instantiation, or what's that called
            > officially?
            >>
            >
            That's called "explicit specialization" (the 'template<>' bit is usually
            a dead giveaway). When it comes to explicit specialization, the class
            itself and the members of the class are pretty much independent
            templates. You can perform explicit specialization on them
            independently. You can explicitly specialize the entire class template
            (meaning that you'll have to redefine the whole thing from scratch), or
            you can explicitly specialize the members (without specializing the
            entire class). The latter is what's done in the above code.
            >
            Of course, once you decided to explicitly specialize the entire class
            template for type 'T', you can no longer explicitly specialize just the
            members for the same type 'T'.
            Oh, I thought explicit specialization of class template members
            wasn't allowed? Oh wait, that was explicit specialization of
            member templates, right? <sigh>

            Schobi

            Comment

            • Andrey Tarasevich

              #7
              Re: Class template specialization

              Hendrik Schober wrote:
              >
              Oh, I thought explicit specialization of class template members
              wasn't allowed? Oh wait, that was explicit specialization of
              member templates, right? <sigh>
              Right. It is a completely different issue.

              BTW, even that is allowed, as long as you explicitly specialize the
              enclosing template as well

              template <class Tstruct C {
              template <class Ustruct D {};
              };

              template<templa te<struct C<int>::D<doubl e{}; // OK

              --
              Best regards,
              Andrey Tarasevich

              Comment

              • Hendrik Schober

                #8
                Re: Class template specialization

                Andrey Tarasevich wrote:
                Hendrik Schober wrote:
                > Oh, I thought explicit specialization of class template members
                > wasn't allowed? Oh wait, that was explicit specialization of
                > member templates, right? <sigh>
                >
                Right. It is a completely different issue.
                >
                BTW, even that is allowed, as long as you explicitly specialize the
                enclosing template as well
                >
                template <class Tstruct C {
                template <class Ustruct D {};
                };
                >
                template<templa te<struct C<int>::D<doubl e{}; // OK
                Thanks.
                So the only thing disallowed would be explicit specialization
                of member templates of unspecialized class templates?

                Schobi

                Comment

                Working...