Topic: Function template specializations and overloading


Author: "Gary Powell" <gary.powell@sierra.com>
Date: 1998/01/15
Raw View
I'm trying to write a fixed point class (practice with templates mostly is
the reason but it should be useful when I'm done.) So I thought I'd add the
numeric_limits<class T> stuff from <limits>.

Thus I ended up with:
template < class T, int Width> class FixedPt {
  ...stuff using T and width to do fixed point math...
};

template< class T, int Width>
class numeric_limits< FixedPt< T, Width> > {    // error here
stuff using T, Width that satisfiy the numeric_limits interface. ....

};

I thought most of the questions that need to be answered in numeric_limits
can be answered by using the type T specified to FixedPt and shifted by the
Width.

The complier Microsoft VC 5.0 complians about '>" found before ';' Is is
broken, ie not up to the standard, or am I misunderstanding how to write
this bit of code. i.e. my code is broken.

  -Gary-


[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: "Scott Stevens" <scotts@inter-intelli.com>
Date: 1998/01/09
Raw View
I have some questions regarding specialization of function templates and
overloading.

1) Is there such a thing as a partial specialization of a function
template?  Given:
 template<class T> T sqrt(T);
 template<class T> complex<T> sqrt(complex<T>);
is the second template a partial specialization of the first?  Or does it
overload the first declaration?  (Or both?)

2) Is the following a valid C++ program?  If so, what should the output be?

 #include <iostream>

 template< class T >
 void Foo( T, T )
 { std::cout << "General case" << std::endl; }

 template<>
 void Foo( const char *a, const char* )
 { std::cout << a << std::endl; }

 void Foo( const char*, const char* b )
 { std::cout << b << std::endl; }

 int main()
 {
  const char* one = "One";
  const char* two = "Two";
  const char* three = "Three";
  const char* four = "Four";

  Foo( one, two );
  Foo< const char* >( three, four );
  Foo( "Five", "Six" );
  Foo< const char* >( "Seven", "Eight" );

  return 0;
 }
(This compiles without error under Microsoft VC++ 5.0.  The result when run
is:
 One
 Three
 General case
 Seven
but if you move the non-template definition of Foo before the definition of
Foo<const char*>, the result is:
 Two
 Four
 General case
 Eight
Go figure.)

3) I'm not sure I understand the intent (or ramifications) of the following
excerpt from the draft C++ standard (CD2, 14.5.5 Function templates):

 3 The signature of a function template specialization consists
 of the signature of the function template and of the actual
 template arguments (whether explicitly specified or deduced).

 4 The signature of a function template consists of its function
 signature, its return type and its template parameter list. The
 names of the template parameters are significant only for
 establishing the relationship between the template parameters
 and the rest of the signature.

Thanks in advance for any light you can shed on these for me.

--
Scott Stevens (scotts@inter-intelli.com)
Interactive Intelligence, Inc. (http://www.inter-intelli.com)
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: "C. Grant" <camg100@hermes.cam.ac.uk>
Date: 1998/01/10
Raw View
Scott Stevens wrote:

>
> 2) Is the following a valid C++ program?  If so, what should the output be?
>
>         #include <iostream>
>
>         template< class T >
>         void Foo( T, T )
>         { std::cout << "General case" << std::endl; }
>
>         template<>
>         void Foo( const char *a, const char* )
>         { std::cout << a << std::endl; }
>
>         void Foo( const char*, const char* b )
>         { std::cout << b << std::endl; }
>
>         int main()
>         {
>                 const char* one = "One";
>                 const char* two = "Two";
>                 const char* three = "Three";
>                 const char* four = "Four";
>
>                 Foo( one, two );
>                 Foo< const char* >( three, four );
>                 Foo( "Five", "Six" );
>                 Foo< const char* >( "Seven", "Eight" );
>
>                 return 0;
>         }
> (This compiles without error under Microsoft VC++ 5.0.  The result when run
> is:
>         One
>         Three
>         General case
>         Seven
> but if you move the non-template definition of Foo before the definition of
> Foo<const char*>, the result is:
>         Two
>         Four
>         General case
>         Eight
> Go figure.)
>

My understanding of the draft-2 grammar rules [gram.temp] is that a
template may not have a null parameter list, so that "template<>" is
invalid.

Maybe null template-parameter lists should be allowed, but I can't
really see their purpose.

As for your output, your compiler chooses "Five", "Six" as char*, so
correctly chooses Foo<char*> for that.  In the other cases, it probably
just chooses the first function/template that matches it, as your
compiler obviously did not detect a clash.

Microsoft probably did not think to check for this clash, as it was not
mentioned in the draft-2 standard, because the clash could not occur if
the compiler rejected empty template-parameter lists.

-- Calum
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: "Brock" <peabody@npcinternational.com>
Date: 1998/01/10
Raw View
On the same subject here is something that generates an "ambiguos function
call" on MSVC 5.0.  Is this valid or not?

template <class T, class U> void f(const T& t,const U& u) {    /* default
action */ }

template <class U> void f(const int& t, const U& u) { /* more specified */}

int
main() {

    int x = 0;
    double y = 0.0;

    f(y,y);    // ok

    f(x,y);    // error

    return 0;
}

I was going to use this technique to generate multi-method-like behavior.

Thanks,
Brock
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Alexandre Oliva <oliva@dcc.unicamp.br>
Date: 1998/01/10
Raw View
Brock  writes:

> template <class T, class U> void f(const T& t,const U& u) {    /* default=
 action */ }

> template <class U> void f(const int& t, const U& u) { /* more specified *=
/}

=46rom my reading of [temp.func.order], there's nothing that makes the
second template function more specialized than the first one, but I
myself would expect it to be.  Perhaps there's something that could be
improved in the rules?  Or in my reading abilities? :-)

-- =

Alexandre Oliva
mailto:oliva@dcc.unicamp.br mailto:aoliva@acm.org
http://www.dcc.unicamp.br/~oliva
Universidade Estadual de Campinas, SP, Brasil
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Alexandre Oliva <oliva@dcc.unicamp.br>
Date: 1998/01/10
Raw View
Scott Stevens writes:

> I have some questions regarding specialization of function templates and
> overloading.

> 1) Is there such a thing as a partial specialization of a function
> template?  Given:
>  template<class T> T sqrt(T);
>  template<class T> complex<T> sqrt(complex<T>);
> is the second template a partial specialization of the first?  Or does it
> overload the first declaration?  (Or both?)

There's no such thing as partial specialization of a function
template, as there is partial specialization of class templates.
Functions are always overloaded, but there is a partial ordering of
template (full) specializations that makes specializations of the
second template be preferred over specializations of the first, unless
explicit template arguments are specified.

> 2) Is the following a valid C++ program?  If so, what should the output be?

Yes, it is valid.

First, a function template is defined.
Then, you define an explicit specialization of that template.  It is
not a partial specialization, as the template argument list is empty.
T is deduced from the parameter types to be `const char *'
Finally, you define a non-template function whose argument list is
exactly the same as the template function Foo<const char*>.  There's a
rule that says that non-template functions are preferred over template
ones by the overload resolution mechanism, unless template arguments
are specified at the call point.

>   Foo( one, two );

 prints `Two', since the non-template function is invoked

>   Foo< const char* >( three, four );

 prints `One', because the specialization Foo<const char*> is called.

>   Foo( "Five", "Six" );

 prints `Six', because "Five" has type `const char[5]' and
"Six" has type `const char[4]'.  There's no exact match, so standard
conversions apply.  Both arguments are converted to `const char *',
and overload resolution selects the non-template candidate function
over the template one.

>   Foo< const char* >( "Seven", "Eight" );

 prints `Seven' because both arguments have type `const
char[6]'.  They're both converted to `const char *', and, since a
template function with a `const char *' template-argument is demanded,
the template explicit specialization is called.

  If no template argument had been specified, and there were
a template function like this:

template <class T> void Foo(T&,T&);

the specialization Foo<const char[6]> might have been selected.

> 3) I'm not sure I understand the intent (or ramifications) of the following
> excerpt from the draft C++ standard (CD2, 14.5.5 Function templates):

>  3 The signature of a function template specialization consists
>  of the signature of the function template and of the actual
>  template arguments (whether explicitly specified or deduced).

The signature of a specialization of a function template cannot be
simply the signature of the function template (that is, its name and
its argument list) because, given the following declarations:
template <class T> void f();
template <int I> void f();
f<long> and f<1> would have the same signature.

>  4 The signature of a function template consists of its function
>  signature, its return type and its template parameter list. The
>  names of the template parameters are significant only for
>  establishing the relationship between the template parameters
>  and the rest of the signature.

this means that, given the following declarations:
template <int I> void f();
template <int J> void f();
they are not an overloading, just a duplicate declaration (which is
not an error).

--
Alexandre Oliva
mailto:oliva@dcc.unicamp.br mailto:aoliva@acm.org
http://www.dcc.unicamp.br/~oliva
Universidade Estadual de Campinas, SP, Brasil
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]