Topic: Template function overloading
Author: Andreas Scherer <andreas.scherer@pobox.com>
Date: 1998/10/02 Raw View
Terence Kelling wrote:
>
> In the last function:
>
> void myFunc(double);
>
> You are not specializing a template function. You are creating a
> regular C-type function. There is a distinction. Regular C-functions
> are given precidence in overload selection before any template
> functions. I would highly recommend reading Lippman's C++ Primer 3rd
> ed. section 10.8 pages 522-530 for a extremely clear explination on
> the subject.
Well, making "void myFunc(double);" a regular function was intended, and
it is definitely not the cause for the compiler errors reported.
Moreoever, Stroustrup uses a similar construct in section 13.3.2
"Function Template Overloading" on page 336.
A followup of this thread already reports a solution that works for both
egcs 1.1 and vc++ 5, fixing the namespace bug in my original posting and
presenting a workaround to a small mishap of vc++ 5.
-- Andreas
---
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Andreas Scherer <andreas.scherer@pobox.com>
Date: 1998/10/02 Raw View
Jerry Coffin wrote:
>=20
> No, it is not. The most obvious problem is that the standard library
> is all in namespace std.
Touch=E9e! (A second problem was the test for _MSC_VER, which is _equal_
to 1100 for VC++ 5.)
> Here's some correct code that's otherwise almost identical to your's
[...see Jerry's posting for details...]
It would have been much simpler for this small example to say "using
namespace std;" instead of qualifying each element explicitely.
> Since none of the other compilers implements the standard library
> correctly, I've made no attempt at making the code work with anything
> but VC++ 5.x. From my testing, I'd guess that if it had a reasonably
> conforming library, egcs would also handle this code correctly.
Negative. "g++ -Wall -o overload overload.cxx" compiles your code
without any warning, but the resulting program prints
Function version A
Function version A
Function version C
on invocation. The version with a "const std::vector<T>" argument gives
the expected answer "Function version B" when invoked with a vector.
Any idea what's going on?
-- Andreas
---
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Andreas Scherer <andreas.scherer@pobox.com>
Date: 1998/10/02 Raw View
AllanW@my-dejanews.com wrote:
>
> I'm pretty sure it is legal, except that you made two mistakes:
> * VC5.0 defines MSC_VER as 1100. So in your first line,
> < should be <=
> * In the first set of #include's, you'll also need "using
> namespace std;" because your code makes no other
> reference to this namespace.
Indeed, I forgot to add this line after running VC++ 5 on a different
machine. Also Borland C++ 5 complained about "vector<T>" in the global
namespace.
> > template< class T >
> > void myFunc( const vector< T >& )
> // ^^^^^ If you remove the "const" keyword, it will work
> for VC5.0
GREAT!!! Thanks for this workaround, Allan.
-- Andreas
---
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: sbnaran@localhost.localdomain (Siemel Naran)
Date: 1998/10/02 Raw View
On 02 Oct 98 12:26:10 GMT, Andreas Scherer <andreas.scherer@pobox.com> wrote:
>It would have been much simpler for this small example to say "using
>namespace std;" instead of qualifying each element explicitely.
Author: sbnaran@localhost.localdomain (Siemel Naran)
Date: 1998/10/03 Raw View
On 02 Oct 98 12:25:36 GMT, Andreas Scherer <andreas.scherer@pobox.com> wrote:
>Terence Kelling wrote:
>> In the last function:
>>
>> void myFunc(double);
>>
>> You are not specializing a template function. You are creating a
>> regular C-type function. There is a distinction. Regular C-functions
>> are given precidence in overload selection before any template
>> functions. I would highly recommend reading Lippman's C++ Primer 3rd
>> ed. section 10.8 pages 522-530 for a extremely clear explination on
>> the subject.
OK. But what you call a "regular C-type function" I would call an
"ordinary non-template function". (BTW, I didn't read this book.
I did read Stroustrup and write a small test program).
This causes a compile error:
template <class T> void myFunc(T& x) { ... }
template <> void myFunc(double x) { ... } // error
The template specialization is invalid because it must specialize T&.
That is, this here works:
template <class T> void myFunc(T& x) { ... }
template <> void myFunc(double& x) { ... } // ok (also "const double&")
However, it is more efficient to pass lightweight value types by
value. So this is the best solution:
template <class T> void myFunc(T& x) { ... }
void myFunc(double x) { ... } // ok
>Well, making "void myFunc(double);" a regular function was intended, and
>it is definitely not the cause for the compiler errors reported.
>Moreoever, Stroustrup uses a similar construct in section 13.3.2
>"Function Template Overloading" on page 336.
He writes on page 337: "For ordinary functions, ordinary overloading
rules (7.4) apply". In short, for template arguments of (template) funcs,
there is no conversion of the arguments. But for non-template funcs of
template funcs and for non-template funcs , there is conversion of the
arguments. Hence,
template <class T> void myFunc(const T& x) { ... }
void myFunc(double x) { ... }
myFunc(3.0); // calls myFunc(const double&)
myFunc(3.0f); // calls myFunc(const double&) // implicit conversion
myFunc(3); // calls myFunc(const double&) // implicit conversion
template <class T> void myFunc(const T& x) { ... }
template <> void myFunc(const double& x) { ... }
myFunc(3.0); // calls myFunc(const double&)
myFunc(3.0f); // calls myFunc(const float&)
myFunc(3); // calls myFunc(const int&)
--
----------------------------------
Siemel B. Naran (sbnaran@uiuc.edu)
----------------------------------
---
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: AllanW@my-dejanews.com
Date: 1998/09/30 Raw View
In article <3610D88A.7A2CF3B@pobox.com>,
Andreas Scherer <andreas.scherer@pobox.com> wrote:
> Could the audience of this group please confirm that the following code
> is in fact conforming to the C++ standard? From the four compilers
> listed in the introducing preprocessor switch only egcs 1.1 was able to
> create a running program that produces the expected output.
I'm pretty sure it is legal, except that you made two mistakes:
* VC5.0 defines MSC_VER as 1100. So in your first line,
< should be <=
* In the first set of #include's, you'll also need "using
namespace std;" because your code makes no other
reference to this namespace.
I've also noted one change required to make it run on VC5.
Your example is correct, but VC5 can't handle it. (Perhaps
VC6 is better at this, I don't know.)
> #if ( 1100 < _MSC_VER ) || defined __GNUG__
#if ( 1100 <= _MSC_VER ) || defined __GNUG__
// ^^^^ Visual C++ 5.0 defines _MSC_VER as 1100
> /* Visual C++ 5.0 oder egcs 1.1a */
> #include <iostream>
> #include <vector>
using namespace std; // Needed since your code doesn't use std::
> #else /* Visual C++ 4.1 or Borland C++ 5.01 */
> #include <iostream.h>
> #include <vector.h>
> #endif
> template< class T >
> void myFunc( const T& )
> {
> cout << "Function version A" << endl;
> }
> template< class T >
> void myFunc( const vector< T >& )
// ^^^^^ If you remove the "const" keyword, it will work for VC5.0
> {
> cout << "Function version B" << endl;
> }
> void myFunc( double )
> {
> cout << "Function version C" << endl;
> }
> int main( void )
> {
> myFunc( 42 ); // Function version A expected
> myFunc( vector< double >() ); // Function version B expected
> myFunc( 3.141529 ); // Function version C expected
> return 0;
> }
In your call to version B, VC5 doesn't seem to prefer
const vector<T>&
over
const T&
and so it reports the call as ambiguous. Sorry, I don't yet have
access to VC6 so I can't tell if this is fixed there.
--
AllanW@my-dejanews.com is a "Spam Magnet" -- never read.
Please reply in USENET only, sorry.
-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/rg_mkgrp.xp Create Your Own Free Member Forum
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Terence Kelling <kelling@arlut.utexas.edu>
Date: 1998/09/30 Raw View
In the last function:
void myFunc(double);
You are not specializing a template function. You are creating a regular C-type
function. There is a distinction. Regular C-functions are given precidence in
overload selection before any template functions. I would highly recommend
reading Lippman's C++ Primer 3rd ed. section 10.8 pages 522-530 for a extremely
clear explination on the subject.
Terence Kelling
Siemel Naran wrote:
> This looks fine. What was your error message? Each overloaded func
> specializes the one that came before it. But you may need the
> template<> syntax. This tells the compiler, hey I'm specializing an
> existing template, not defining a new one.
>
> >template< class T >
> >void myFunc( const T& )
> OK.
>
> >template< class T >
> >void myFunc( const vector< T >& )
> OK
>
> >void myFunc( double )
> Try this:
> template<>
> void myFunc( double )
---
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Andreas Scherer <andreas.scherer@pobox.com>
Date: 1998/09/30 Raw View
Siemel Naran wrote:
>
> This looks fine. What was your error message?
- Visual C++ 4.1 reports on "void myFunc( double )"
Compiling...
overload.cxx
C:\Tmp\overload\overload.cxx(31) : error C2668: 'myFunc' : ambiguous
call to overloaded function (new behavior; please see help)
Error executing cl.exe.
overload.exe - 1 error(s), 0 warning(s)
and on "template<> void myFunc( double )"
Compiling...
overload.cxx
C:\Tmp\overload\overload.cxx(22) : error C2952: template declaration
must specify parameter list
C:\Tmp\overload\overload.cxx(31) : error C2668: 'myFunc' : ambiguous
call to overloaded function (new behavior; please see help)
Error executing cl.exe.
overload.exe - 2 error(s), 0 warning(s)
- Visual C++ 5.0 reports on "void myFunc( double )"
Compiling...
overload.cxx
G:\MAILBOX\ANDREAS\overload.cxx(32) : error C2667: 'myFunc' : none of 2
overload have a best conversion
G:\MAILBOX\ANDREAS\overload.cxx(32) : error C2668: 'myFunc' : ambiguous
call to overloaded function
Error executing cl.exe.
overload.exe - 2 error(s), 0 warning(s)
and on "template<> void myFunc( double )"
Compiling...
overload.cxx
G:\MAILBOX\ANDREAS\overload.cxx(25) : error C2912: explicit
specialization; 'void __cdecl myFunc(double)' is not a function template
G:\MAILBOX\ANDREAS\overload.cxx(25) : error C2912: explicit
specialization; 'void __cdecl myFunc(double)' is not a function template
G:\MAILBOX\ANDREAS\overload.cxx(32) : error C2667: 'myFunc' : none of 2
overload have a best conversion
G:\MAILBOX\ANDREAS\overload.cxx(32) : error C2668: 'myFunc' : ambiguous
call to overloaded function
Error executing cl.exe.
overload.exe - 4 error(s), 0 warning(s)
With "template<> void myFunc( const double& )" I get
Compiling...
overload.cxx
G:\MAILBOX\ANDREAS\overload.cxx(32) : error C2667: 'myFunc' : none of 2
overload have a best conversion
G:\MAILBOX\ANDREAS\overload.cxx(32) : error C2668: 'myFunc' : ambiguous
call to overloaded function
Error executing cl.exe.
overload.exe - 2 error(s), 0 warning(s)
- Borland C++ 5.01 reports on "void myFunc( double )"
Ambiguity between 'myFunc(const vector<T> &)' and 'myFunc(const T &)'
and on "template<> void myFunc( double )" as well as on "template<> void
myFunc( const double& )"
Invalid template argument list
Note that both Visual C++ 5.0 and Borland C++ 5.01 need "using namespace
std;" prior to the first appearance of "vector". This does not alter the
faulty behavior of Visual C++ 4.1 nor the correct behavior of egcs 1.1.
A similar posting to news:microsoft.public.vstudio.development was not
(yet) met with an answer, so I do not know if Visual C++ 6 would help
solve my problem (which is buried in a real-world application, where
tons of trivial "myFunc"s with identical bodies are getting written just
because <class T> can be something like "<class T> vector< T >").
-- Andreas
---
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: jcoffin@taeus.com (Jerry Coffin)
Date: 1998/09/30 Raw View
In article <3610D88A.7A2CF3B@pobox.com>, andreas.scherer@pobox.com
says...
> Could the audience of this group please confirm that the following code
> is in fact conforming to the C++ standard?
No, it is not. The most obvious problem is that the standard library
is all in namespace std. Here's some correct code that's otherwise
almost identical to your's:
#include <iostream>
#include <vector>
template< class T >
void myFunc( const T& )
{
std::cout << "Function version A" << std::endl;
}
template< class T >
void myFunc( std::vector< T >& )
{
std::cout << "Function version B" << std::endl;
}
void myFunc( double )
{
std::cout << "Function version C" << std::endl;
}
int main( void )
{
myFunc( 42 ); // Function version A expected
myFunc( std::vector< double >() ); // Function version B expected
myFunc( 3.141529 ); // Function version C expected
return 0;
}
Since none of the other compilers implements the standard library
correctly, I've made no attempt at making the code work with anything
but VC++ 5.x. From my testing, I'd guess that if it had a reasonably
conforming library, egcs would also handle this code correctly.
You'll note that I've removed the `const' on the version that takes a
vector -- it appears that VC++ figures that std::vector<double> is a
type (which it is) and figures that your std::vector<double> matches
`const T&' and `const std::vector<T>' equally well. I haven't gone
over the template specialization rules in enough detail to be sure,
but my first guess is that this is wrong, and vector specialization
should be preferred.
--
Later,
Jerry.
The Universe is a figment of its own imagination.
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Andreas Scherer <andreas.scherer@pobox.com>
Date: 1998/09/29 Raw View
Could the audience of this group please confirm that the following code
is in fact conforming to the C++ standard? From the four compilers
listed in the introducing preprocessor switch only egcs 1.1 was able to
create a running program that produces the expected output.
-- Andreas Scherer
#if ( 1100 < _MSC_VER ) || defined __GNUG__
/* Visual C++ 5.0 oder egcs 1.1a */
#include <iostream>
#include <vector>
#else /* Visual C++ 4.1 or Borland C++ 5.01 */
#include <iostream.h>
#include <vector.h>
#endif
template< class T >
void myFunc( const T& )
{
cout << "Function version A" << endl;
}
template< class T >
void myFunc( const vector< T >& )
{
cout << "Function version B" << endl;
}
void myFunc( double )
{
cout << "Function version C" << endl;
}
int main( void )
{
myFunc( 42 ); // Function version A expected
myFunc( vector< double >() ); // Function version B expected
myFunc( 3.141529 ); // Function version C expected
return 0;
}
---
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: sbnaran@fermi.ceg.uiuc.edu (Siemel Naran)
Date: 1998/09/29 Raw View
On 29 Sep 98 18:01:20 GMT, Andreas Scherer <andreas.scherer@pobox.com> wrote:
>Could the audience of this group please confirm that the following code
>is in fact conforming to the C++ standard? From the four compilers
>listed in the introducing preprocessor switch only egcs 1.1 was able to
>create a running program that produces the expected output.
This looks fine. What was your error message? Each overloaded func
specializes the one that came before it. But you may need the
template<> syntax. This tells the compiler, hey I'm specializing an
existing template, not defining a new one.
>template< class T >
>void myFunc( const T& )
OK.
>template< class T >
>void myFunc( const vector< T >& )
OK
>void myFunc( double )
Try this:
template<>
void myFunc( double )
--
----------------------------------
Siemel B. Naran (sbnaran@uiuc.edu)
----------------------------------
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]