Connecting Tech Pros Worldwide Help | Site Map

template instantiation error

Hunter Hou
Guest
 
Posts: n/a
#1: Jul 22 '05
Hello,

I'm trying one example of <<the C++ programming language>> Page 865

int f( int );
template< class T > T g( T t ) { return f( t ); }
char c = g( 'a' ); ************
char f( char );

Stroustrup said **** line is wrong because alternative resolution of f( t )
are possible.

But I used g++ in mingw to compile above code, there's nothing wrong. My
code is like this:



//template_study.cpp

int f( int );
template< class T > T g( T t ) { return f( t ); }
char c = g( 'a' );
char f( char );

int main() { return 0; }





Who would like to shed some light on me?

And who can explain further about template instantiation and namespace? I
don't quite understand what Stroustrup says.


Thanks,
Hunter


tom_usenet
Guest
 
Posts: n/a
#2: Jul 22 '05

re: template instantiation error


On Wed, 9 Jun 2004 16:22:04 +0800, "Hunter Hou" <hyhou@lucent.com>
wrote:
[color=blue]
>Hello,
>
>I'm trying one example of <<the C++ programming language>> Page 865
>
>int f( int );
>template< class T > T g( T t ) { return f( t ); }
>char c = g( 'a' ); ************[/color]

The above would call int f(int) on a conforming compiler.
[color=blue]
>char f( char );
>
>Stroustrup said **** line is wrong because alternative resolution of f( t )
>are possible.[/color]

I doubt he said exactly that. He may have said something about
dependent name resolution?
[color=blue]
>But I used g++ in mingw to compile above code, there's nothing wrong.[/color]

You need g++ 3.4 (see www.mingw.org). This is the first GCC version to
include a partial implementation of two phase name lookup in
templates.
[color=blue]
>And who can explain further about template instantiation and namespace? I
>don't quite understand what Stroustrup says.[/color]

int f( int );
The above declares a global function int f(int).

template< class T > T g( T t )
{
return f( t );
The name "f" used here is a dependent name - that is, the meaning of
it depends on the type of T. This means that lookup doesn't happen
immediately.

}

char c = g( 'a' );
Instead, lookup of the f in g is deferred until the point of
instantiation, here. Names "f" are looked up both at the point of
definition of g (where int f(int) is found), and at the point of
instantiation using argument dependent lookup (where again, int f(int)
is found, since char f(char) hasn't been declared yet). So the call to
g calls int f(int).

char f( char );
This function isn't called.

Note that GCC 3.4 still has some bugs with name lookup, so it will
call char f(char) even though it hasn't been declared at the point of
instantiation. I assume this will be fixed in GCC 3.5. However, a few
compilers do get your example right - notably Comeau C++ and other EDG
based compilers such as Intel C++ (they output a linker error for the
missing definition of int f(int) - GCC outputs a error for char
f(char) which is incorrect).

There is only one book that covers these name lookup issues in detail,
and that's Vandevoorde and Josuttis' book, "C++ Templates". Worth a
read (although I haven't read it myself).

Tom
--
C++ FAQ: http://www.parashift.com/c++-faq-lite/
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
Michiel Salters
Guest
 
Posts: n/a
#3: Jul 22 '05

re: template instantiation error


"Hunter Hou" <hyhou@lucent.com> wrote in message news:<ca6h4k$8ds@netnews.proxy.lucent.com>...[color=blue]
> Hello,
>
> I'm trying one example of <<the C++ programming language>> Page 865
>
> int f( int );
> template< class T > T g( T t ) { return f( t ); }
> char c = g( 'a' ); ************
> char f( char );
>
> Stroustrup said **** line is wrong because alternative resolution of f( t )
> are possible.[/color]

Are you sure the example wasn't

int f( int );
template< class T > T g( T t ) { return f( t ); }
char f( char );
char c = g( 'a' ); ************


The problem with this code is that f(t) depends on the meaning of t.
This meaning changes between the definition of g<T> and the call
g<char>('a'). Initially , the name f refers to the single function
f(int), but later it refers to the overload set f(int) and f(char).

Don't change the meaning of names in templates between the template
definition and the template usage, unless you have a very good book
or understand chapter 14 of the C++ standard.

Regards,
Michiel Salters
New_user
Guest
 
Posts: n/a
#4: Jul 22 '05

re: template instantiation error


> I'm trying one example of <<the C++ programming language>> Page 865[color=blue]
>
> int f( int );
> template< class T > T g( T t ) { return f( t ); }
> char c = g( 'a' ); ************
> char f( char );
>
> Stroustrup said **** line is wrong because alternative resolution of f( t )
> are possible.[/color]

I don't remember Bjarne's words exactly. But this example compilable.
"Error" is: f(int) will be called, no fun(char): it's so-named two
phase name-lookup (I don't have mingw, but if he calls f(char) == he
does not know rules :).

For example, my icc calls fun(int).
tom_usenet
Guest
 
Posts: n/a
#5: Jul 22 '05

re: template instantiation error


On Wed, 09 Jun 2004 13:35:39 +0100, tom_usenet
<tom_usenet@hotmail.com> wrote:
[color=blue]
>On Wed, 9 Jun 2004 16:22:04 +0800, "Hunter Hou" <hyhou@lucent.com>
>wrote:
>[color=green]
>>Hello,
>>
>>I'm trying one example of <<the C++ programming language>> Page 865
>>
>>int f( int );
>>template< class T > T g( T t ) { return f( t ); }
>>char c = g( 'a' ); ************[/color]
>
>The above would call int f(int) on a conforming compiler.
>[color=green]
>>char f( char );
>>
>>Stroustrup said **** line is wrong because alternative resolution of f( t )
>>are possible.[/color]
>
>I doubt he said exactly that. He may have said something about
>dependent name resolution?[/color]

Ok, I take back my earlier answer. The code in fact is well-formed,
but has undefined behaviour. Since the call to "f" has a better match
if all extern functions are considered than it does it you only take
ones found in the instantiation context (i.e. f(char) is a better
match than f(int), but isn't visible at the instantiation point), the
call to f is undefined.

Apologies to Stroustrup and to GCC 3.4, which doesn't have a bug after
all.

(See 14.6.4.2 in the standard)

Tom
--
C++ FAQ: http://www.parashift.com/c++-faq-lite/
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
Hunter Hou
Guest
 
Posts: n/a
#6: Jul 22 '05

re: template instantiation error


[color=blue][color=green][color=darkred]
>>>I'm trying one example of <<the C++ programming language>> Page 865
>>>
>>>int f( int );
>>>template< class T > T g( T t ) { return f( t ); }
>>>char c = g( 'a' ); ************[/color]
>>
>>The above would call int f(int) on a conforming compiler.
>>
>>[color=darkred]
>>>char f( char );
>>>
>>>Stroustrup said **** line is wrong because alternative resolution of f( t )
>>>are possible.[/color]
>>
>>I doubt he said exactly that. He may have said something about
>>dependent name resolution?[/color]
>
>
> Ok, I take back my earlier answer. The code in fact is well-formed,
> but has undefined behaviour. Since the call to "f" has a better match
> if all extern functions are considered than it does it you only take
> ones found in the instantiation context (i.e. f(char) is a better
> match than f(int), but isn't visible at the instantiation point), the
> call to f is undefined.
>[/color]



Stroustrup says

We could generate the specialization g<char>(char) at the point of
instantiation and get f(int) called. Alternatively, we could wait and
generate the specialization at the end of the translation unit and get
f(char) called. Consequently, the call g('a') is an error.

tom_usenet
Guest
 
Posts: n/a
#7: Jul 22 '05

re: template instantiation error


On 9 Jun 2004 08:55:45 -0700, tpochep@mail.ru (New_user) wrote:
[color=blue][color=green]
>> I'm trying one example of <<the C++ programming language>> Page 865
>>
>> int f( int );
>> template< class T > T g( T t ) { return f( t ); }
>> char c = g( 'a' ); ************
>> char f( char );
>>
>> Stroustrup said **** line is wrong because alternative resolution of f( t )
>> are possible.[/color]
>
>I don't remember Bjarne's words exactly. But this example compilable.
>"Error" is: f(int) will be called, no fun(char): it's so-named two
>phase name-lookup (I don't have mingw, but if he calls f(char) == he
>does not know rules :).
>
>For example, my icc calls fun(int).[/color]

The code has undefined behaviour - f(char) or f(int) might be called,
or neither.

Tom
--
C++ FAQ: http://www.parashift.com/c++-faq-lite/
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
tom_usenet
Guest
 
Posts: n/a
#8: Jul 22 '05

re: template instantiation error


On Thu, 10 Jun 2004 11:13:40 +0800, Hunter Hou <hyhou@lucent.com>
wrote:
[color=blue]
>Stroustrup says
>
>We could generate the specialization g<char>(char) at the point of
>instantiation and get f(int) called. Alternatively, we could wait and
>generate the specialization at the end of the translation unit and get
>f(char) called. Consequently, the call g('a') is an error.[/color]

That sounds right. Which bit don't you understand? Do you understand
"dependent names"? "Argument dependent lookup"? "Implicit template
instantiation and point of instantiation"? Those are the mechanisms
that are involved here.

Tom
--
C++ FAQ: http://www.parashift.com/c++-faq-lite/
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
Closed Thread