C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Some observations about template instantiation

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated)
View previous topic :: View next topic  
Author Message
Matthias Hofmann
Guest





PostPosted: Fri Jul 16, 2004 12:18 am    Post subject: Some observations about template instantiation Reply with quote



Hello!

I have recently become aware of certain curiosities related to template
instantiations. Consider, as an example, the following code:

// BEGIN CODE
#include <iostream>

using namespace std;

struct A {};

struct B
{
// An A is convertible to a B.
B( const A& a = A() ) {}
};

template <class T> void f( const T& r )
{
// Tell me who you are.
cout << typeid( r ).name() << endl;
}

int main()
{
// Instantiates "void f( const B& )".
f( B() );

// Instantiates "void f( const A& )", although
// "void f( const B& )" could be used.
f( A() );

return 0;
}
// END CODE

In the above example, the compiler instantiates to distinct functions for
struct A and struct B, although it could pass A to the function it
instantiated for B. However, you would have to force the compiler to that
that:

f
I guess that the standard prescribes that behaviour somewhere, and actually
this is not yet what I find curious. What indeed puzzled me was that the
whole matter changes when default parameters come into play:

template <class T> void f( const T& r = B() ) // Note the default parameter.
{
// Same as before.
}

int main()
{
// Error, cannot deduce template argument.
f();

return 0;
}

A few days ago someone has explained to me in another thread that this
behaviour is due to the reason that the default argument expression is valid
for any type T for which there is an implicit conversion from B to T. If I
do not want to pass the functional argument to f(), I have to pass it a
template argument:

f<B>();

The problem I got is that I do not see any difference between passing a
functional argument explicitly or using the default parameter, I think the
folowing to calls should be the same:

f( B() );
f(); // Default argument is B().

The first call is also "valid for any type T for which there is an implicit
conversion from B to T", but the compiler still decides for B. So what is
the rationale behind that?

Best regards,

Matthias Hofmann









[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Tokyo Tomy
Guest





PostPosted: Fri Jul 16, 2004 11:22 am    Post subject: Re: Some observations about template instantiation Reply with quote



"Matthias Hofmann" <hofmann (AT) anvil-soft (DOT) com> wrote

Quote:
Hello!

I have recently become aware of certain curiosities related to template
instantiations. Consider, as an example, the following code:

// BEGIN CODE
#include <iostream

using namespace std;

struct A {};

struct B
{
// An A is convertible to a B.
B( const A& a = A() ) {}
};

template {
// Tell me who you are.
cout << typeid( r ).name() << endl;
}

int main()
{
// Instantiates "void f( const B& )".
f( B() );

// Instantiates "void f( const A& )", although
// "void f( const B& )" could be used.
f( A() );

return 0;
}
// END CODE

In the above example, the compiler instantiates to distinct functions for
struct A and struct B, although it could pass A to the function it
instantiated for B. However, you would have to force the compiler to that
that:

f
I guess that the standard prescribes that behaviour somewhere, and actually
this is not yet what I find curious. What indeed puzzled me was that the
whole matter changes when default parameters come into play:

template <class T> void f( const T& r = B() ) // Note the default parameter.
{
// Same as before.
}

int main()
{
// Error, cannot deduce template argument.
f();

return 0;
}

A few days ago someone has explained to me in another thread that this
behaviour is due to the reason that the default argument expression is valid
for any type T for which there is an implicit conversion from B to T. If I
do not want to pass the functional argument to f(), I have to pass it a
template argument:

f<B>();

The problem I got is that I do not see any difference between passing a
functional argument explicitly or using the default parameter, I think the
folowing to calls should be the same:

f( B() );
f(); // Default argument is B().

The first call is also "valid for any type T for which there is an implicit
conversion from B to T", but the compiler still decides for B. So what is
the rationale behind that?


I think this is understandable.
The template function with default parameter needs the following two
steps.

1. Instantiate template function f(const T& r)
2. Assign default parameter B() to r

At the step 1 for instantiation, the complier must know the type of
r, but does not yet know, because the assignment (initialization) is
not yet executed.

However, you may still not understand why f(B())also works fine. So, I
add another step to the above procedure.

0. Try to find a type information from the parameter list
1. Instantiate template function f(const T& r)
2. Assign default parameter B() to r
(if the parameter is not supplied from the parameter list.)

This is only my hypothesis for more discussion. Welcome any objection.

Regards,
T Tomy

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Matthias Hofmann
Guest





PostPosted: Sat Jul 17, 2004 10:11 am    Post subject: Re: Some observations about template instantiation Reply with quote



Tokyo Tomy <hosoda (AT) jtec (DOT) or.jp> schrieb in im Newsbeitrag:
[email]49c1da0b.0407160059.27162ff1 (AT) posting (DOT) google.com[/email]...
Quote:
"Matthias Hofmann" <hofmann (AT) anvil-soft (DOT) com> wrote


[snip]

Quote:

I think this is understandable.
The template function with default parameter needs the following two
steps.

1. Instantiate template function f(const T& r)
2. Assign default parameter B() to r

At the step 1 for instantiation, the complier must know the type of
r, but does not yet know, because the assignment (initialization) is
not yet executed.

However, you may still not understand why f(B())also works fine. So, I
add another step to the above procedure.

0. Try to find a type information from the parameter list
1. Instantiate template function f(const T& r)
2. Assign default parameter B() to r
(if the parameter is not supplied from the parameter list.)

This is only my hypothesis for more discussion. Welcome any objection.

Your hypothesis sounds plausible. However, I expected the compiler to do the
following steps:

1. Try to find type information from the parameter list
2. If no arguments are passed, get type information from default parameters
3. Instantiate template function
4. Assign actual parameter to r if available, otherwise use default
parameter

I guess that the standard simply does not require the compiler to do these
steps. Instead, type information is only taken from the actual parameters or
from additional template arguments. It's not that I have a problem with it,
I was simply curious...

Best regards,

Matthias Hofmann



[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Roshan
Guest





PostPosted: Tue Jul 20, 2004 9:41 pm    Post subject: Re: Some observations about template instantiation Reply with quote

Quote:
1. Try to find type information from the parameter list
2. If no arguments are passed, get type information from default parameters
3. Instantiate template function
4. Assign actual parameter to r if available, otherwise use default
parameter

Parameter lists are not used for deducing types. Arguments lists are.
-Roshan


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.