This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug c++/15629] Function templates, overloads, and friend name injection
- From: "bangerth at dealii dot org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: 24 May 2004 15:19:32 -0000
- Subject: [Bug c++/15629] Function templates, overloads, and friend name injection
- References: <20040524081805.15629.ywhu@nmi.iii.org.tw>
- Reply-to: gcc-bugzilla at gcc dot gnu dot org
------- Additional Comments From bangerth at dealii dot org 2004-05-24 15:19 -------
OK, something is really screwed up here. Take this:
-----------------
#include <iostream>
#define PRINT std::cerr << __PRETTY_FUNCTION__ << std::endl
template<int a, int b> class T;
template<int a, int b> void func(T<a, b> * t) { PRINT; }
template<int a> void func(T<a, 3> * t) { PRINT; }
template<int a, int b> struct T {
friend void func<a, b>(T<a, b> * t);
friend void func<a> (T<a, 3> * t);
void foo();
};
template<int a, int b> void T<a, b>::foo() {
func((T<2,3>*)0);
}
int main() {
func((T<2,3>*)0);
T<2,3>().foo();
}
-----------------------
Note that the call to func in main() is the same as the one in foo(), so
it should really yield the same result. Alas, with gcc3.4, we get:
g/x> /home/bangerth/bin/gcc-3.4-pre/bin/c++ x.cc ; ./a.out
void func(T<a, 3>*) [with int a = 2]
void func(T<a, b>*) [with int a = 2, int b = 3]
On the other hand, if we revert the order of the two calls in main(), we get
a different result, namely a call to the general T<a,b> template as in the
second line above. My inclination is to say that this is due to the fact that
we only instantiate T<2,3> in the second call in main(), since the cast
to (T<2,3>*)0 does not require instantiation of the template. Now, how that
can affect the result I don't know -- presumably it has something to do with
injecting the friend functions into the global namespace. This explains
why reverting the calls in main() changes the result.
What evades me, however, is why injecting the names should make any
difference? Note that if I remove the friend declarations altogether,
then we get two calls to the <a,3> template, irrespective of the call
order in main(). I tend to think that this is what we should get in all
cases, but would like to have a second opinion...
W.
--
What |Removed |Added
----------------------------------------------------------------------------
Summary|Function overloading doesn't|Function templates,
|happen when I use friend |overloads, and friend name
|function templates in class |injection
|templates. |
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=15629