Strange compile problem with function templates involving pointers to virtual member functions of a derived class. In the attached test code, compiler doesn't seem to think the virtual functions w::a() and w::b() exists in the derived class unless addresses are first copied into pointer variables. g++ test.cc -otest test.cc: In function `int main(unsigned int, const char *const *)': test.cc:49: no matching function for call to `c<w>::fails_sometimes (int &, void (y::*)(int) const)' test.cc:50: no matching function for call to `c<w>::fails_sometimes (const char *&, void (y::*)(const char *) const)' make: *** [test] Error 1 Release: gcc version 2.95.2 19991024 (release) Environment: RedHat Linux 6.2. Also fails under Redhat 7.0 with unofficial gcc-2.96. How-To-Repeat: #include <iostream> class y { public: virtual void a (int n) const { } virtual void b (const char *s) const { } }; class w: public y { }; template <class m> class c { public: template<class d> void works (const d& x) const { cerr << x << endl; } template<class d> void fails_sometimes (const d& x, void (m::*func)(d) const) const { cerr << x << endl; } }; int main (unsigned argc, const char *const argv[]) { int n = 3; const char *s = "hey!"; c<w> c1; // This works OK... c1.works(n); c1.works(s); // This works OK... void (w::*a_func)(int) const = &w::a; void (w::*b_func)(const char *) const = &w::b; // This works OK... c1.fails_sometimes(n, a_func); c1.fails_sometimes(s, b_func); // This fails compilation, but should pass... c1.fails_sometimes(n, &w::a); c1.fails_sometimes(s, &w::b); }
State-Changed-From-To: open->analyzed State-Changed-Why: Confirm as a bug.
From: Wolfgang Bangerth <bangerth@ticam.utexas.edu> To: gcc-bugs@gcc.gnu.org, <gcc-gnats@gcc.gnu.org> Cc: Subject: Re: c++/950: Template lookup problem Date: Sun, 10 Nov 2002 14:46:04 -0600 (CST) A reduced testcase for this one is -------------------------------------------- struct B { void a (int n); }; struct D: public B {}; template <typename T> struct X { template<typename Y> static void foo (const Y&, void (T::*)(Y)); }; int main () { int n = 3; X<D>::foo(n, &D::a); } -------------------------------------- The error I get is this one: x.cc: In function `int main()': x.cc:11: error: no matching function for call to `X<D>::foo(int&, void (B::*)(int))' Thus, the compiler cannot find a match for X::foo, since &D::a is immediately converted to &B::a, i.e. to a pointer to member function of the _base_ class, although we have taken a p-t-m-f of the derived class. I don't know what the standard says on this one, but at least the failure mode is clear now. The problem can be worked around using a temporary variable of type void (D::*)(int) or an explicit cast. Regards Wolfgang ------------------------------------------------------------------------- Wolfgang Bangerth email: bangerth@ticam.utexas.edu www: http://www.ticam.utexas.edu/~bangerth
From: Wolfgang Bangerth <bangerth@apex68.ticam.utexas.edu> To: gcc-gnats@gcc.gnu.org Cc: Subject: c++/950: Template lookup problem Date: Thu, 14 Nov 2002 14:34:53 -0600 Re-confirmed with 3.3 CVS from 2002-11-10 and 3.2.1 pre from the same date.
From: "Giovanni Bajo" <giovannibajo@libero.it> To: <gcc-gnats@gcc.gnu.org>, <gcc-bugs@gcc.gnu.org>, <nobody@gcc.gnu.org>, <gcc-prs@gcc.gnu.org>, <peteb@sitera.com> Cc: "Wolfgang Bangerth" <bangerth@ices.utexas.edu> Subject: Re: c++/950: [2003-01-01] Template lookup problem Date: Thu, 10 Apr 2003 19:48:23 +0200 http://gcc.gnu.org/cgi-bin/gnatsweb.pl?cmd=view%20audit-trail&database=gcc&p r=950 Reconfirmed with 2.95 -> 3.3 20030401. Giovanni Bajo
still happens with the mainline (20030524). pr950.cc: In function `int main()': pr950.cc:12: error: no matching function for call to `X<D>::foo(int&, void (B::*)(int))'
*** Bug 9032 has been marked as a duplicate of this bug. ***
*** Bug 11906 has been marked as a duplicate of this bug. ***
*** Bug 13063 has been marked as a duplicate of this bug. ***
*** Bug 18681 has been marked as a duplicate of this bug. ***
EDG likes this.
Still happens with 4.1.2
Still happens with gcc version 4.4.0 20080801 (experimental) [trunk revision 138448]
5.3.1 [expr.unary.op] paragraph 3: ...If the member is a non-static member of class C of type T, the type of the result is “pointer to member of class C of type T.” [ Example: struct A { int i; }; struct B : A { }; // has type int A::* ... &B::i ... — end example ] So, the type of &D::a is the same as the type of &B::a, and this is not a bug.
Created attachment 19035 [details] patch If this were a bug, this would be the fix.
Actually, this is issue 203, so I'll suspend it instead of closing. http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#203
(In reply to Jason Merrill from comment #15) > Actually, this is issue 203, so I'll suspend it instead of closing. > > http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#203 Issue 203 has been resolved: http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#203
Not a bug then.