Re: Function pointers and default arguments
On Aug 5, 10:39 pm, Gianni Mariani <gi3nos...@mariani.ws> wrote:
James Kanze wrote:
On Aug 5, 2:13 am, Gianni Mariani <gi3nos...@mariani.ws> wrote:
James Kanze wrote:
[Note that as far as I can tell, this comment has nothing to
do with what preceding in the thread.]
Interesting; this code compiles in gcc but not on comeau or VC++ 2005.
int f( int p = 5 )
{
return p;
}
template <typename T>
T F( T fp )
{
return fp;
}
#include <iostream>
int main()
{
std::cout << F( f )() << "\n";
I missed the second pair of parentheses in the above.
}
Ok, so who is wrong, GCC or Comeau + VC++ ?
What operator<< is being called?
int ... I think.
... The type of F(f) is "int (*)(
int )" (a "function" type is treated as a pointer to function
type when it is a function parameter). There's no such
operator<< in the standard, and there's no implicit conversion
from a function pointer to anything which has an operator<<, so
a priori, it shouldn't compile.
What does the output look like?
5
... Could it be that g++ is
(illegally) converting the function pointer to void*?
No. I don't think so.
Doesn't really look like it, does it.
It's actually an interesting case. While the default argument
is not part of the type, it definitly is associated with the
name somehow. It's not part of the type, since you can write
something like:
int f( int p = 5 ) ;
int g( int p = 10 ) ;
int (*pf)( int ) = condition ? f : g ;
or, for that matter, if a header declares simply:
int f( int ) ;
you can add an:
int f( int = 5 ) ;
in one source file, and an:
int f( int = 10 ) ;
in another, and have different default arguments for the same
function in different translation units---or even in different
scopes in the same translation unit.
Just out of curiousity, I modified your program to the
following:
#include <iostream>
int
f( int p = 42 )
{
return p ;
}
int g(
int p = 5 )
{
return p ;
}
int count = 0 ;
template< typename T >
T F( T fp )
{
static bool instance = false ;
if ( ! instance ) {
++ count ;
instance = true ;
}
return fp ;
}
int
main()
{
std::cout << F(f)() << std::endl ;
std::cout << F(g)() << std::endl ;
std::cout << count << std::endl ;
return 0 ;
}
G++ (4.1.0) compiles it and outputs:
42
42
1
Which looks very much like a bug to me: it's (correctly)
treating the two functions f and g as having the same type (and
thus, only a single instantiation of the template), but
associates the default argument for the first instantiation with
all of the instantiations. (It would be interesting to see what
happens when F is instantiated in several different translation
units, with different default arguments.)
With regards to the orignal problem: whether (&f)() should use
the default argument or not, to be frank, I don't think that the
standard is as clear as it could be about this. I'll raise the
point in comp.std.c++, and see what they say there. (The
declaration f has a default argument associated with it, but how
far does this "annotation" propagate in an expression?)
--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orient=E9e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S=E9mard, 78210 St.-Cyr-l'=C9cole, France, +33 (0)1 30 23 00 34