template partial specialization

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Paul MG

    template partial specialization

    Hi

    Template partial specialization always seems like a fairly
    straightforward concept - until I try to do it :).

    I am trying to implement the input sequence type (from Stroustrup
    section 18.3.1, 'Iseq'). I want the version for containers that he
    gives, but also to provide a specialization for construction from a
    pair<It,It> (eg because that is returned by equal_range()). [Iseq is
    actually implemented as a pair<> - but that is a separate issue.]

    Here is what I have:

    // ---------------------------------------------------------------

    // A type representing an 'input sequence':

    template<class In>
    class Iseq : public pair<In, In> {
    public:
    Iseq(In i1, In i2) : pair<In, In>(i1, i2) {}
    bool IsEmpty() const { return first == second; }
    };

    // A helper function to make one (since ctors can't
    // infer the types of template arguments):

    template<class C>
    Iseq<typename C::iterator> iseq(C& c) {
    return Iseq<typename C::iterator>(c. begin(), c.end());
    }

    // A specialisation for pairs:

    template<class T>
    Iseq<T> iseq_p(pair<T, T> p) {
    return Iseq<T>(p.first , p.second);
    }

    // An overloaded version of STL find() taking an input sequence:

    template<class In, class T>
    In find(Iseq<In> r, const T& v) { return find(r.first, r.second, v);
    }

    // And finally, a client:

    Iseq<MMIt> FindMemberships (UserReference member) {
    return iseq_p( memberships_.eq ual_range(membe r) );
    }
    MMIt MemberAt(UserRe ference member, Path path) {
    return find(FindMember ships(member), make_pair(membe r,
    path));
    }

    // ---------------------------------------------------------------


    This works. But only because I have renamed my 'specialisation ' of
    iseq() for pairs to iseq_p. I don't want to (and don't think I have
    to) do that, for this or any further specialisations . Simply replacing
    'iseq_p' with 'iseq' in the above causes the compiler (gcc2.95) to
    attempt to use the first definition of iseq, and it (rightly)
    complains that pair<>::iterato r does not exist. What mistake am I
    making?

    [ As an aside: Stroustrup makes Iseq<T> publicly inherit pair<T,T>. I
    might be inclined to make it privately inherit it - surely no client
    wants to use the pair<> interface? ]
  • Chandra Shekhar Kumar

    #2
    Re: template partial specialization



    Paul MG wrote:
    [color=blue]
    > Hi
    >
    > Template partial specialization always seems like a fairly
    > straightforward concept - until I try to do it :).
    >
    > I am trying to implement the input sequence type (from Stroustrup
    > section 18.3.1, 'Iseq'). I want the version for containers that he
    > gives, but also to provide a specialization for construction from a
    > pair<It,It> (eg because that is returned by equal_range()). [Iseq is
    > actually implemented as a pair<> - but that is a separate issue.]
    >
    > Here is what I have:
    >
    > // ---------------------------------------------------------------
    >
    > // A type representing an 'input sequence':
    >
    > template<class In>
    > class Iseq : public pair<In, In> {
    > public:
    > Iseq(In i1, In i2) : pair<In, In>(i1, i2) {}
    > bool IsEmpty() const { return first == second; }
    > };
    >
    > // A helper function to make one (since ctors can't
    > // infer the types of template arguments):
    >
    > template<class C>
    > Iseq<typename C::iterator> iseq(C& c) {
    > return Iseq<typename C::iterator>(c. begin(), c.end());
    > }
    >
    > // A specialisation for pairs:
    >
    > template<class T>
    > Iseq<T> iseq_p(pair<T, T> p) {
    > return Iseq<T>(p.first , p.second);
    > }[/color]

    this is not specialisation of class Iseq for pairs if u replace iseq_p
    with Iseq. it is a function.
    the specialisation is:

    template <>
    template <class T>
    class Iseq<pair<T,T> >
    {
    public:
    Iseq(pair<T,T> pairv): pair<T,T>(pairv .first, pairv.second)
    };

    this is not the solution to yr problem though, but it will give u the
    basic idea.
    [color=blue]
    >
    >
    > // An overloaded version of STL find() taking an input sequence:
    >
    > template<class In, class T>
    > In find(Iseq<In> r, const T& v) { return find(r.first, r.second, v);
    > }
    >
    > // And finally, a client:
    >
    > Iseq<MMIt> FindMemberships (UserReference member) {
    > return iseq_p( memberships_.eq ual_range(membe r) );
    > }
    > MMIt MemberAt(UserRe ference member, Path path) {
    > return find(FindMember ships(member), make_pair(membe r,
    > path));
    > }
    >
    > // ---------------------------------------------------------------
    >
    >
    > This works. But only because I have renamed my 'specialisation ' of
    > iseq() for pairs to iseq_p. I don't want to (and don't think I have
    > to) do that, for this or any further specialisations . Simply replacing
    > 'iseq_p' with 'iseq' in the above causes the compiler (gcc2.95) to
    > attempt to use the first definition of iseq, and it (rightly)
    > complains that pair<>::iterato r does not exist. What mistake am I
    > making?
    >
    > [ As an aside: Stroustrup makes Iseq<T> publicly inherit pair<T,T>. I
    > might be inclined to make it privately inherit it - surely no client
    > wants to use the pair<> interface? ][/color]

    Comment

    • Chandra Shekhar Kumar

      #3
      Re: template partial specialization



      Paul MG wrote:
      [color=blue]
      > Hi
      >
      > Template partial specialization always seems like a fairly
      > straightforward concept - until I try to do it :).
      >
      > I am trying to implement the input sequence type (from Stroustrup
      > section 18.3.1, 'Iseq'). I want the version for containers that he
      > gives, but also to provide a specialization for construction from a
      > pair<It,It> (eg because that is returned by equal_range()). [Iseq is
      > actually implemented as a pair<> - but that is a separate issue.]
      >
      > Here is what I have:
      >
      > // ---------------------------------------------------------------
      >
      > // A type representing an 'input sequence':
      >
      > template<class In>
      > class Iseq : public pair<In, In> {
      > public:
      > Iseq(In i1, In i2) : pair<In, In>(i1, i2) {}
      > bool IsEmpty() const { return first == second; }
      > };
      >
      > // A helper function to make one (since ctors can't
      > // infer the types of template arguments):
      >
      > template<class C>
      > Iseq<typename C::iterator> iseq(C& c) {
      > return Iseq<typename C::iterator>(c. begin(), c.end());
      > }
      >
      > // A specialisation for pairs:
      >
      > template<class T>
      > Iseq<T> iseq_p(pair<T, T> p) {
      > return Iseq<T>(p.first , p.second);
      > }[/color]

      this is not specialisation of class Iseq for pairs if u replace iseq_p
      with Iseq. it is a function.
      the specialisation is:

      template <>
      template <class T>
      class Iseq<pair<T,T> >
      {
      public:
      Iseq(pair<T,T> pairv): pair<T,T>(pairv .first, pairv.second)
      };

      this is not the solution to yr problem though, but it will give u the
      basic idea.
      [color=blue]
      >
      >
      > // An overloaded version of STL find() taking an input sequence:
      >
      > template<class In, class T>
      > In find(Iseq<In> r, const T& v) { return find(r.first, r.second, v);
      > }
      >
      > // And finally, a client:
      >
      > Iseq<MMIt> FindMemberships (UserReference member) {
      > return iseq_p( memberships_.eq ual_range(membe r) );
      > }
      > MMIt MemberAt(UserRe ference member, Path path) {
      > return find(FindMember ships(member), make_pair(membe r,
      > path));
      > }
      >
      > // ---------------------------------------------------------------
      >
      >
      > This works. But only because I have renamed my 'specialisation ' of
      > iseq() for pairs to iseq_p. I don't want to (and don't think I have
      > to) do that, for this or any further specialisations . Simply replacing
      > 'iseq_p' with 'iseq' in the above causes the compiler (gcc2.95) to
      > attempt to use the first definition of iseq, and it (rightly)
      > complains that pair<>::iterato r does not exist. What mistake am I
      > making?
      >
      > [ As an aside: Stroustrup makes Iseq<T> publicly inherit pair<T,T>. I
      > might be inclined to make it privately inherit it - surely no client
      > wants to use the pair<> interface? ][/color]

      Comment

      • Paul MG

        #4
        Re: template partial specialization

        > > // A specialisation for pairs:[color=blue][color=green]
        > >
        > > template<class T>
        > > Iseq<T> iseq_p(pair<T, T> p) {
        > > return Iseq<T>(p.first , p.second);
        > > }[/color]
        >
        > That isn't a specialization, but a function overload.[/color]

        Hmmmm... so if you define a templated function

        template<class T> iseq(T);

        and then later add

        template<> iseq(SomeType);

        then the second is a function overload not a specialization? That is
        what I am trying to do (I think). Its just that when SomeType is
        'pair<T1,T2>', you need to specify T1 and T2 too so you can't just say
        'template<>' like I have here...
        [color=blue][color=green]
        > >Simply replacing
        > >'iseq_p' with 'iseq' in the above causes the compiler (gcc2.95) to
        > >attempt to use the first definition of iseq, and it (rightly)
        > >complains that pair<>::iterato r does not exist. What mistake am I
        > >making?[/color]
        >
        > Using a 3 year old compiler. Upgrade to gcc 3.0+ and it will work
        > fine. The missing feature is "partial template function ordering",
        > which knows how to choose the best match amongst different template
        > specializations that match a function call.[/color]

        I have other places in the code where it correctly chooses the 'most
        specific' implementation of a templated function just like what I
        outlined above. So I don't think it is total lack of compiler support
        - it could be a failure to support something in this specific case I
        suppose, yes.
        [color=blue][color=green]
        > >[ As an aside: Stroustrup makes Iseq<T> publicly inherit pair<T,T>. I
        > >might be inclined to make it privately inherit it - surely no client
        > >wants to use the pair<> interface? ][/color]
        >
        > Your find overload does...[/color]

        Only cos I copied it out of Stroustrup. I would have preferred to
        inherit Iseq<T> privately from pair<T,T>, and give it accessors
        begin() and end() which return pair<T,T>::firs t and pair<T,T>::seco nd.

        But I am unwilling to assume that I am cleverer than Stroustrup :).
        Someone let me know my error?

        cheers!

        pmg

        Comment

        • Paul MG

          #5
          Re: template partial specialization

          > > // A specialisation for pairs:[color=blue][color=green]
          > >
          > > template<class T>
          > > Iseq<T> iseq_p(pair<T, T> p) {
          > > return Iseq<T>(p.first , p.second);
          > > }[/color]
          >
          > this is not specialisation of class Iseq for pairs if u replace iseq_p
          > with Iseq. it is a function.[/color]

          ['with iseq' is what I meant, I presume what you meant too]

          i think what i was trying to do was create a specialisation of the
          template function iseq, not the class Iseq (see my response to tom).
          are you suggesting then that i am trying the wrong approach?
          [color=blue]
          > the specialisation is:
          >
          > template <>
          > template <class T>
          > class Iseq<pair<T,T> >
          > {
          > public:
          > Iseq(pair<T,T> pairv): pair<T,T>(pairv .first, pairv.second)
          > };
          >
          > this is not the solution to yr problem though, but it will give u the
          > basic idea.[/color]

          Never seen that 'template<> template<class T>' thing before.
          Interesting. So the 'template<>' shows that this is a partial
          specialisation, the 'class Iseq<pair<T, T> >' says that it is a
          specialisation for pairs, and the 'template <class T>' bit in between
          states that pair<T,T> itself requires a template parameter T. Is that
          right?

          Anyway, now I can do this then:

          pair<It, It> myRange = getRange();
          find(ISeq(myRan ge), someValue);

          ?

          Would rather specialise/overload the factory function iseq() than the
          class itself though, if only because otherwise it is unsymmetrical
          with the other case of constructing off a collection (which uses the
          factory function so that the template type can be inferred):

          vector<Foo> foos = getFoos();
          find(iseq(foos) , someValue);
          // which is just neater than:
          // find(ISeq<Foo:: iterator>(foos) , someValue));

          Hope this makes sense, thanks for your input,

          cheers
          pmg

          Comment

          • Chandra Shekhar Kumar

            #6
            Re: template partial specialization


            [color=blue]
            > Hmmmm... so if you define a templated function
            >
            > template<class T> iseq(T);
            >
            > and then later add
            >
            > template<> iseq(SomeType);
            >
            > then the second is a function overload not a specialization?[/color]

            this is template function specialisation.
            [color=blue]
            > That is
            > what I am trying to do (I think). Its just that when SomeType is
            > 'pair<T1,T2>', you need to specify T1 and T2 too so you can't just say
            > 'template<>' like I have here...[/color]

            yes, u shud write:

            template<> template <typename T1, typename T2> iseq(pair<T1, T2>)


            Comment

            • Chandra Shekhar Kumar

              #7
              Re: template partial specialization


              sorry...i messed up a bit....
              what i meant is:
              template <> is not partial specialization, it is fully specialisation :-))

              Comment

              • tom_usenet

                #8
                Re: template partial specialization

                On 25 Jun 2003 01:22:37 -0700, paulmg@digitalb rain.com (Paul MG)
                wrote:
                [color=blue][color=green][color=darkred]
                >> > // A specialisation for pairs:
                >> >
                >> > template<class T>
                >> > Iseq<T> iseq_p(pair<T, T> p) {
                >> > return Iseq<T>(p.first , p.second);
                >> > }[/color]
                >>
                >> That isn't a specialization, but a function overload.[/color]
                >
                >Hmmmm... so if you define a templated function
                >
                > template<class T> iseq(T);
                >
                >and then later add
                >
                > template<> iseq(SomeType);
                >
                >then the second is a function overload not a specialization?[/color]

                It is a specialization (ignoring the missing return type). It is
                better to write it as:

                template<>
                Iseq<WhateverTy pe> iseq<SomeType>( SomeType c);

                so that the compiler knows with overload of iseq you are specializing
                (by matching the bit between the <> with the signatures), if there is
                more than one possibility (*).

                The overload version would be:

                Iseq<SomeType> iseq(SomeType);


                That is[color=blue]
                >what I am trying to do (I think). Its just that when SomeType is
                >'pair<T1,T2> ', you need to specify T1 and T2 too so you can't just say
                >'template<>' like I have here...[/color]

                Ahh, so you are trying to partially specialize a function template.
                That isn't possible in C++, so you have to use overloading. If partial
                specialization existed, the syntax would be analogous to class partial
                specialization:

                template<class T>
                Iseq<T> iseq<pair<T, T> >(pair<T, T> p) {
                return Iseq<T>(p.first , p.second);
                }

                but if you feed that to your compiler, you'll get an error. In any
                case, partial specialization wouldn't really make sense even if it did
                exist, since you're changing the return type from T::iterator to, in
                effect, T::first_type.

                What you have is two completely different template functions that are
                related only by the fact that they share the same name.
                [color=blue]
                >[color=green][color=darkred]
                >> >Simply replacing
                >> >'iseq_p' with 'iseq' in the above causes the compiler (gcc2.95) to
                >> >attempt to use the first definition of iseq, and it (rightly)
                >> >complains that pair<>::iterato r does not exist. What mistake am I
                >> >making?[/color]
                >>
                >> Using a 3 year old compiler. Upgrade to gcc 3.0+ and it will work
                >> fine. The missing feature is "partial template function ordering",
                >> which knows how to choose the best match amongst different template
                >> specializations that match a function call.[/color]
                >
                >I have other places in the code where it correctly chooses the 'most
                >specific' implementation of a templated function just like what I
                >outlined above. So I don't think it is total lack of compiler support
                >- it could be a failure to support something in this specific case I
                >suppose, yes.[/color]

                I just tried it in g++, and it looks like the problem might be that
                g++ doesn't properly implement SFINAE (substitution failure is not an
                error), instead making the substitution of the pair into the first
                overload an error, when all it should do is discard it from the
                overload list.

                So in fact, partial ordering doesn't directly affect this issue, since
                the first overload should be eliminated before the compiler gets to
                partial ordering.
                [color=blue]
                >[color=green][color=darkred]
                >> >[ As an aside: Stroustrup makes Iseq<T> publicly inherit pair<T,T>. I
                >> >might be inclined to make it privately inherit it - surely no client
                >> >wants to use the pair<> interface? ][/color]
                >>
                >> Your find overload does...[/color]
                >
                >Only cos I copied it out of Stroustrup. I would have preferred to
                >inherit Iseq<T> privately from pair<T,T>, and give it accessors
                >begin() and end() which return pair<T,T>::firs t and pair<T,T>::seco nd.
                >
                >But I am unwilling to assume that I am cleverer than Stroustrup :).
                >Someone let me know my error?[/color]

                I suppose Iseq doesn't need accessors in the same way that pair
                doesn't need them. It is a fundamental type that simply holds two
                iterators.

                However, adding accessors won't hurt anything except possibly
                performance, depending on whether you return by value or reference.

                Tom

                Comment

                • tom_usenet

                  #9
                  Re: template partial specialization

                  On Wed, 25 Jun 2003 02:11:11 +0530, Chandra Shekhar Kumar
                  <chandra.kumar@ oracle.com> wrote:
                  [color=blue]
                  >
                  >[color=green]
                  >> Hmmmm... so if you define a templated function
                  >>
                  >> template<class T> iseq(T);
                  >>
                  >> and then later add
                  >>
                  >> template<> iseq(SomeType);
                  >>
                  >> then the second is a function overload not a specialization?[/color]
                  >
                  >this is template function specialisation.
                  >[color=green]
                  >> That is
                  >> what I am trying to do (I think). Its just that when SomeType is
                  >> 'pair<T1,T2>', you need to specify T1 and T2 too so you can't just say
                  >> 'template<>' like I have here...[/color]
                  >
                  >yes, u shud write:
                  >
                  > template<> template <typename T1, typename T2> iseq(pair<T1, T2>)[/color]

                  What is the above supposed to be? It isn't legal code, in any case.

                  Tom

                  Comment

                  • Chandra Shekhar Kumar

                    #10
                    Re: template partial specialization

                    >[color=blue][color=green]
                    > >
                    > > template<> template <typename T1, typename T2> iseq(pair<T1, T2>)[/color]
                    >
                    > What is the above supposed to be? It isn't legal code, in any case.[/color]

                    see the code below and run it, u will understand what i meant by
                    above.......... .....(use a good compiler ::-))

                    #include <iostream>
                    #include <map>

                    using namespace std;

                    template<class T> h(T a) { cout << "h::" << a << endl; }

                    template<> template<class T1, class T2> h(pair<T1, T2>& p) { cout << "pair::"
                    << p.first << ":::" << p.second << endl;}

                    int main()
                    {
                    h(20);
                    pair<int, float> p(20, 30.34);
                    h(p);
                    }



                    Comment

                    • Chandra Shekhar Kumar

                      #11
                      Re: template partial specialization

                      > That is[color=blue][color=green]
                      > >what I am trying to do (I think). Its just that when SomeType is
                      > >'pair<T1,T2> ', you need to specify T1 and T2 too so you can't just say
                      > >'template<>' like I have here...[/color]
                      >
                      > Ahh, so you are trying to partially specialize a function template.
                      > That isn't possible in C++.[/color]

                      u r wrong....
                      see the code below::


                      #include <iostream>
                      #include <map>

                      using namespace std;

                      template<class T> h(T a) { cout << "h::" << a << endl; }

                      template<> template<class T1, class T2> h(pair<T1, T2>& p) { cout << "pair::"
                      << p.first << ":::" << p.second << endl;}

                      int main()
                      {
                      h(20);
                      pair<int, float> p(20, 30.34);
                      h(p);
                      }



                      Comment

                      • Chandra Shekhar Kumar

                        #12
                        Re: template partial specialization

                        so , now the question is when to choose function templates, and when function
                        overloading.... .
                        the limitation of function templates is that they donot scale well.
                        what i mean is: with the function templates having 2 or more arguments cann't
                        be fully specilaized.

                        see the code below:

                        #include <iostream>
                        #include <map>

                        using namespace std;

                        template<class T1, class T2> f(T1 a, T2 b) { cout << a << ":" << b << endl;}

                        //partial specialization of f......

                        template<class T1> f(T1 a, int b) { cout << "partial::" << a << ":" << b <<
                        endl;}


                        //fully specialisation of f.....not legal code...so commented.....

                        //template<> f(int a, int b) { cout << "fully:::" << a << ":" << b << endl;}


                        template <class T> g(T a) { cout << "g:: " << a << endl;}

                        //fully specialisation of g.....legal here coz g takes only one argument.....

                        template<> g(int a) { cout << "fully::g:: :" << a << endl;}



                        template<class T> h(T a) { cout << "h::" << a << endl; }

                        //fully specialisation. ..same as above....:-)))

                        template<> template<class T1, class T2> h(pair<T1, T2>& p) { cout << "pair::"
                        << p.first << ":::" << p.second << endl;}


                        int main()
                        {
                        f(5.45,4.56);
                        f(34.45, 3);
                        f(2, 3);
                        g(3.45);
                        g(2);

                        h(20);
                        pair<int, float> p(20, 30.34);
                        h(p);
                        }


                        Comment

                        • Victor Bazarov

                          #13
                          Re: template partial specialization

                          "Chandra Shekhar Kumar" <chandra.kumar@ oracle.com> wrote...[color=blue][color=green]
                          > >[color=darkred]
                          > > >
                          > > > template<> template <typename T1, typename T2> iseq(pair<T1, T2>)[/color]
                          > >
                          > > What is the above supposed to be? It isn't legal code, in any case.[/color]
                          >
                          > see the code below and run it, u will understand what i meant by
                          > above.......... .....(use a good compiler ::-))[/color]

                          See the results below. Perhaps, you need to use a good book?
                          [color=blue]
                          >
                          > #include <iostream>
                          > #include <map>
                          >
                          > using namespace std;
                          >
                          > template<class T> h(T a) { cout << "h::" << a << endl; }
                          >
                          > template<> template<class T1, class T2> h(pair<T1, T2>& p) { cout <<[/color]
                          "pair::"[color=blue]
                          > << p.first << ":::" << p.second << endl;}
                          >
                          > int main()
                          > {
                          > h(20);
                          > pair<int, float> p(20, 30.34);
                          > h(p);
                          > }
                          >[/color]

                          Comeau C/C++ 4.3.1 (Mar 1 2003 20:09:34) for ONLINE_EVALUATI ON_BETA1
                          Copyright 1988-2003 Comeau Computing. All rights reserved.
                          MODE:strict errors C++

                          "ComeauTest .c", line 6: error: omission of explicit type is nonstandard
                          ("int"
                          assumed)
                          template<class T> h(T a) { cout << "h::" << a << endl; }
                          ^

                          "ComeauTest .c", line 6: warning: missing return statement at end of non-void
                          function
                          "h(T) [with T=T]"
                          template<class T> h(T a) { cout << "h::" << a << endl; }
                          ^

                          "ComeauTest .c", line 8: error: omission of explicit type is nonstandard
                          ("int"
                          assumed)
                          template<> template<class T1, class T2> h(pair<T1, T2>& p) { cout <<
                          "pair::"
                          ^

                          "ComeauTest .c", line 8: error: this declaration cannot have multiple
                          "template <...>"
                          clauses
                          template<> template<class T1, class T2> h(pair<T1, T2>& p) { cout <<
                          "pair::"
                          ^

                          "ComeauTest .c", line 6: error: no operator "<<" matches these operands
                          operand types are: std::basic_ostr eam<char,
                          std::char_trait s<char>> << std::pair<int, float>
                          template<class T> h(T a) { cout << "h::" << a << endl; }
                          ^
                          detected during instantiation of
                          "int h(T) [with T=std::pair<int , float>]"

                          4 errors detected in the compilation of "ComeauTest .c".
                          In strict mode, with -tused, Compile failed


                          Comment

                          • Victor Bazarov

                            #14
                            Re: template partial specialization

                            "Chandra Shekhar Kumar" <chandra.kumar@ oracle.com> wrote in message
                            news:3EF8F517.9 4AAA72A@oracle. com...[color=blue][color=green]
                            > > That is[color=darkred]
                            > > >what I am trying to do (I think). Its just that when SomeType is
                            > > >'pair<T1,T2> ', you need to specify T1 and T2 too so you can't just say
                            > > >'template<>' like I have here...[/color]
                            > >
                            > > Ahh, so you are trying to partially specialize a function template.
                            > > That isn't possible in C++.[/color]
                            >
                            > u r wrong....
                            > see the code below::
                            >
                            >
                            > #include <iostream>
                            > #include <map>
                            >
                            > using namespace std;
                            >
                            > template<class T> h(T a) { cout << "h::" << a << endl; }
                            >
                            > template<> template<class T1, class T2> h(pair<T1, T2>& p) { cout <<[/color]
                            "pair::"[color=blue]
                            > << p.first << ":::" << p.second << endl;}
                            >
                            > int main()
                            > {
                            > h(20);
                            > pair<int, float> p(20, 30.34);
                            > h(p);
                            > }[/color]

                            This code doesn't compile. It's plain bogus. Please try to
                            compile any code before you post it.


                            Comment

                            • tom_usenet

                              #15
                              Re: template partial specialization

                              On Wed, 25 Jun 2003 06:31:52 +0530, Chandra Shekhar Kumar
                              <chandra.kumar@ oracle.com> wrote:
                              [color=blue][color=green]
                              >>[color=darkred]
                              >> >
                              >> > template<> template <typename T1, typename T2> iseq(pair<T1, T2>)[/color]
                              >>
                              >> What is the above supposed to be? It isn't legal code, in any case.[/color]
                              >
                              >see the code below and run it, u will understand what i meant by
                              >above......... ......(use a good compiler ::-))[/color]

                              I have two good compilers (Comeau C++ and G++ 3.2) and neither liked
                              the code. Here's Comeau's error (once I put return types into the
                              function declarations)

                              "main.cpp", line 9: error: this declaration cannot have multiple
                              "template
                              <...>" clauses
                              template<> template<class T1, class T2> void h(pair<T1, T2>& p) {
                              cout << "pai
                              r::"
                              ^
                              [color=blue]
                              >
                              >#include <iostream>
                              >#include <map>
                              >
                              >using namespace std;
                              >
                              >template<cla ss T> h(T a) { cout << "h::" << a << endl; }[/color]

                              Is that meant to be a template function? Where's the return type?
                              [color=blue]
                              >
                              >template<> template<class T1, class T2> h(pair<T1, T2>& p) { cout << "pair::"
                              ><< p.first << ":::" << p.second << endl;}[/color]

                              What the hell is that supposed to be? You have two template parameter
                              lists!

                              What compiler are you using? It appears to be severely broken...

                              Ahh, I just tried g++ 2.95.3 and that seems to compile it (once I put
                              in void return types). But that is a very old non-standard compiler -
                              a standard compiler is required to reject the code. I assume that you
                              intended to write this:

                              #include <iostream>
                              #include <map>

                              using namespace std;

                              template<class T> void h(T a) { cout << "h::" << a << endl; }

                              template<class T1, class T2> void h(pair<T1, T2>& p) { cout <<
                              "pair::"
                              << p.first << ":::" << p.second << endl;}

                              int main()
                              {
                              h(20);
                              pair<int, float> p(20, 30.34);
                              h(p);
                              }

                              which compiles happily on GCC 3.2, Comeau C++, and GCC 2.95 for that
                              matter.

                              Tom

                              Comment

                              Working...