473,386 Members | 1,795 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,386 software developers and data experts.

Template name lookup

Hi,

I can compile the code below with GCC 3.4.2, because function g is a
"dependent name".

template<class T>
void f1(T t)
{
g(t);
}

void g(int i)
{

}

int main()
{
f1<int>(10);
return 0;
}

But if I change the function g to a template function, things became
different. I cannot pass the compilation with GCC 3.4.2, but it works
fine with Visual C/C++ 7.

template<class T>
void f1(T t)
{
g<0>(t);
}

template<int I>
void g(int i)
{

}

int main()
{
f1<int>(10);
return 0;
}

The error message from GCC is:
main.cpp: In function `void f1(T)':
main.cpp:23: error: `g' undeclared (first use this function)
main.cpp:23: error: (Each undeclared identifier is reported only once
for each function it appears in.)
main.cpp: At global scope:
main.cpp:28: error: `template<int I> void g(int)' used prior to
declaration

Why?

Thanks,

Phil

Jul 23 '05 #1
10 1802
ph**********@yahoo.com wrote:
But if I change the function g to a template function, things became
different. I cannot pass the compilation with GCC 3.4.2, but it works
fine with Visual C/C++ 7.

template<class T>
void f1(T t)
{
g<0>(t);
}

template<int I>
void g(int i)
{

}

int main()
{
f1<int>(10);
return 0;
}

The error message from GCC is:
main.cpp: In function `void f1(T)':
main.cpp:23: error: `g' undeclared (first use this function)
main.cpp:23: error: (Each undeclared identifier is reported only once
for each function it appears in.)
main.cpp: At global scope:
main.cpp:28: error: `template<int I> void g(int)' used prior to
declaration

Why?

template<int I>
void g(int i)
{

}
template<class T>
void f1(T t)
{
g<0>(t);
}
int main()
{
f1<int>(10);
return 0;
}

--
Ioannis Vranos

http://www23.brinkster.com/noicys
Jul 23 '05 #2

<ph**********@yahoo.com> wrote in message
news:11**********************@g14g2000cwa.googlegr oups.com...
Hi,

I can compile the code below with GCC 3.4.2, because function g is a
"dependent name".

template<class T>
void f1(T t)
{
g(t);
}

void g(int i)
{

}

int main()
{
f1<int>(10);
return 0;
}

But if I change the function g to a template function, things became
different. I cannot pass the compilation with GCC 3.4.2, but it works
fine with Visual C/C++ 7.

template<class T>
void f1(T t)
{
g<0>(t);
}

template<int I>
void g(int i)
{

}

int main()
{
f1<int>(10);
return 0;
}

The error message from GCC is:
main.cpp: In function `void f1(T)':
main.cpp:23: error: `g' undeclared (first use this function)
main.cpp:23: error: (Each undeclared identifier is reported only once
for each function it appears in.)
main.cpp: At global scope:
main.cpp:28: error: `template<int I> void g(int)' used prior to
declaration

Why?


A first glance at your code suggested a problem with the GCC´s template
instantiation model. The problem is that connected to the point of
instantiation and the order that templates are substituted. For a more
detailed description I´d suggest for example "C++ templates" by David
Vandevoorde & Nicolai Josuttis.

Anyway, you can help yourself easily by putting the definition of g() before
f().

Cheers
Chris
Jul 23 '05 #3

Chris Theis wrote:
<ph**********@yahoo.com> wrote in message
news:11**********************@g14g2000cwa.googlegr oups.com...
Hi,

I can compile the code below with GCC 3.4.2, because function g is a "dependent name".

template<class T>
void f1(T t)
{
g(t);
}

void g(int i)
{

}

int main()
{
f1<int>(10);
return 0;
}

But if I change the function g to a template function, things became different. I cannot pass the compilation with GCC 3.4.2, but it works fine with Visual C/C++ 7.

template<class T>
void f1(T t)
{
g<0>(t);
}

template<int I>
void g(int i)
{

}

int main()
{
f1<int>(10);
return 0;
}

The error message from GCC is:
main.cpp: In function `void f1(T)':
main.cpp:23: error: `g' undeclared (first use this function)
main.cpp:23: error: (Each undeclared identifier is reported only once for each function it appears in.)
main.cpp: At global scope:
main.cpp:28: error: `template<int I> void g(int)' used prior to
declaration

Why?
A first glance at your code suggested a problem with the GCC´s

template instantiation model.


I assume you meant "Visual C++" instead of "GCC" here?
GNU is correct in refusing the code (Visual C++ does not correctly
implement the standard here): You cannot use template arguments
after a name unless it is somehow known that the name denotes a
template.

During the first round of standardization of C++ it was briefly
considered to add new syntax for this very example, but ultimately
it was considered unnecessary. (Something like "template g<0>(t)".)

Daveed

Jul 23 '05 #4

<va*********@gmail.com> wrote in message instantiation model.

[SNIP]
I assume you meant "Visual C++" instead of "GCC" here?
GNU is correct in refusing the code (Visual C++ does not correctly
implement the standard here): You cannot use template arguments
after a name unless it is somehow known that the name denotes a
template. During the first round of standardization of C++ it was briefly
considered to add new syntax for this very example, but ultimately
it was considered unnecessary. (Something like "template g<0>(t)".)


Ooops, thanks for the correction Daveed. Do you happen to know how Visual
C++ treats the instantiation here, so that the unexpectedly code works?

Cheers
Chris
Jul 23 '05 #5

Chris Theis wrote:
[...]
Ooops, thanks for the correction Daveed. Do you happen to know how Visual C++ treats the instantiation here, so that the unexpectedly code

works?

The Microsoft compiler treats templates a bit like macros and basically
doesn't look at template definitions until instantiation time. (Hence
it
is unable to meet the standard 2-phase lookup requirements.) Instead,
it performs instantiation at the end of the translation unit and at
that
time it "replays" the tokens of the template definition with the
template
parameters substituted. In the example under discussion, this
replaying
for "f1<int>" happens after all the source (including the template "g")
has been seen, and therefore "g<0>" is resolved.

A consequence of doing things like this is that you can write
template<class T> void f() {
blah blah // literally, try it!
}

and the compiler will accept the code despite the nonsensical function
body (as long as you don't actually instantiate the template).

(I'm writing this not based on actual knowledge of the VC++ internals,
but based on the analysis of various cases and on knowing how some
other implementation historically worked in the same way.)

(The EDG compiler by default also accepts such example for backward
compatibility reasons. However, in its mode standard-conforming modes
if will issue an error.)

Daveed

Jul 23 '05 #6
va*********@gmail.com wrote:
The Microsoft compiler treats templates a bit like macros and basically
doesn't look at template definitions until instantiation time. (Hence
it
is unable to meet the standard 2-phase lookup requirements.) Instead,
it performs instantiation at the end of the translation unit and at
that
time it "replays" the tokens of the template definition with the
template
parameters substituted. In the example under discussion, this
replaying
for "f1<int>" happens after all the source (including the template "g")
has been seen, and therefore "g<0>" is resolved.

A consequence of doing things like this is that you can write
template<class T> void f() {
blah blah // literally, try it!
}

and the compiler will accept the code despite the nonsensical function
body (as long as you don't actually instantiate the template).

(I'm writing this not based on actual knowledge of the VC++ internals,
but based on the analysis of various cases and on knowing how some
other implementation historically worked in the same way.)

(The EDG compiler by default also accepts such example for backward
compatibility reasons. However, in its mode standard-conforming modes
if will issue an error.)

The above also compiles with Intel C++ 8.1 and VC++ 2005 February 2005 CTP.

Does the 2-phase lookup mean that the function name needs not "be
already in scope" as with the usual functions?

--
Ioannis Vranos

http://www23.brinkster.com/noicys
Jul 23 '05 #7

<va*********@gmail.com> wrote in message
news:11**********************@o13g2000cwo.googlegr oups.com...

Chris Theis wrote:
[...]
Ooops, thanks for the correction Daveed. Do you happen to know how

Visual
C++ treats the instantiation here, so that the unexpectedly code

works?

The Microsoft compiler treats templates a bit like macros and basically
doesn't look at template definitions until instantiation time. (Hence
it
is unable to meet the standard 2-phase lookup requirements.) Instead,
it performs instantiation at the end of the translation unit and at
that
time it "replays" the tokens of the template definition with the
template
parameters substituted. In the example under discussion, this
replaying
for "f1<int>" happens after all the source (including the template "g")
has been seen, and therefore "g<0>" is resolved.

A consequence of doing things like this is that you can write
template<class T> void f() {
blah blah // literally, try it!
}

and the compiler will accept the code despite the nonsensical function
body (as long as you don't actually instantiate the template).

(I'm writing this not based on actual knowledge of the VC++ internals,
but based on the analysis of various cases and on knowing how some
other implementation historically worked in the same way.)

(The EDG compiler by default also accepts such example for backward
compatibility reasons. However, in its mode standard-conforming modes
if will issue an error.)

Daveed


Thanks Daveed, that was very informative!

Chris
Jul 23 '05 #8

Ioannis Vranos wrote:
va*********@gmail.com wrote: [...]
A consequence of doing things like this is that you can write
template<class T> void f() {
blah blah // literally, try it!
}

[...] The above also compiles with Intel C++ 8.1 and VC++ 2005 February 2005 CTP.

(I believe the Intel compiler has a --strict option that will cause
it to use the standard rules.)
Does the 2-phase lookup mean that the function name needs not "be
already in scope" as with the usual functions?


Pretty much. The exception are dependent unqualified calls
with no explicit template arguments. They come in two
variants: (1) your plain function call ("f(x, y)" where x and/or
y is dependent), and (2) simple operator invocations ("x * y"
where x and/or y is dependent). These can still appear
without actually have the function or operator be visible in
the template definition.

Daveed

Jul 23 '05 #9
Thanks for all of the replies.

Phil

Jul 23 '05 #10
Following might be a solution if you have to deal with the case.

template<class P>
void f()
{
P::template get<0>();
}

class A
{
public:
template<int I>
static void get()
{
cout << "hi" << endl;
}
};
int main(int argc, char *argv[])
{
f<A>();
return 0;
}

Phil

Jul 23 '05 #11

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: Brian | last post by:
I have an application that uses an array of values as a "lookup" table and smarty as a template engine. $lookup = "label"; $lookup = "label2"; $lookup = "label"; $lookup = "label2"; In my...
2
by: James Ying | last post by:
Following is the complete code demonstrating the issue: ===================== > cat tt.cc #include <iostream> template <class T> class Base { public: typedef T difference_type; };
7
by: Hunter Hou | last post by:
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 ); ...
8
by: mattias.nissler | last post by:
Hi! Here is a problem I ran into at work. The following example doesn't compile on gcc-4.1: struct cons_end {}; template<typename U,typename Vstruct cons { U elem; V tail;
4
by: Thomas.Zauner | last post by:
Hi, i have to get an aprx. 9 year old code running. back then id did compile but now it doesn't. i have broken down the problem to the following technique which is used quit freq. in the code....
0
by: James Kanze | last post by:
On May 16, 9:34 am, Paavo Helde <nob...@ebi.eewrote:
5
by: Ian Collins | last post by:
Consider the following snippet: struct X { static bool called; }; struct Y : X { Y() { called = true; } // g++ is happy with this }; template <int N>
10
by: Unkown to Xnntp | last post by:
Hello, The following code works (it compiles ok with "g++ test.c"): ++++++++++++++++++++++++++++++++++++++++ template <class Valueclass Test1 { public: int a; };
2
by: puzzlecracker | last post by:
See it a lot but haven't learn the difference between this two in the context of template. Would someone explain it please? Thanks
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.