I'm reporting this against my system compiler (4.1.2 on NetBSD/macppc), but I can reproduce it using all versions from 3.4 (when two-stage name lookup was introduced) to 4.4 - which I was able to test on a linux/amd64 machine with a large collection of compilers installed.
The following code (minimized test case) is rejected with $ g++ -S bug_p.cpp bug_p.cpp: In member function 'bool Node::FooOpNode<_Op>::f() [with _Op = X]': bug_p.cpp:63: instantiated from here bug_p.cpp:54: error: cannot call member function 'bool Node::test(int)' without object If offending call to "test" is qualified as "Node::test", compiler accepts it happily. Yes, I read http://gcc.gnu.org/onlinedocs/gcc/Name-lookup.html#Name-lookup ----8<--------8<---- struct X { int i; }; class Node { public: template <typename _Op> class OpNode; template <typename _Op> class FooOpNode; class FooNode; Node() {} virtual ~Node() {} bool test(int i) { return true; } virtual bool f() { return true; } }; template <typename _Op> class Node::OpNode : public Node { public: typedef OpNode<_Op> OpNodeBase; _Op &op; OpNode(_Op &op) : Node(), op(op) {} // "test" call ok here virtual bool f() { return !test(op.i); } }; template <typename _Op> class Node::FooOpNode : public OpNode<_Op> { public: typedef OpNode<_Op> OpNodeBase; using OpNodeBase::op; typedef FooOpNode<_Op> FooOpNodeBase; FooOpNode(_Op &op) : OpNodeBase(op) {} // "test" call marked as error here // unless qualified as Node::test() virtual bool f() { return // Node:: test(op.i); } }; class Node::FooNode : public FooOpNode<X> { public: FooNode(X &x) : FooOpNodeBase(x) {} }; ----8<--------8<---- -- Summary: Possible bug in name resolution during template instantiation Product: gcc Version: 4.1.2 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: uwe at netbsd dot org GCC build triplet: powerpc--netbsd GCC host triplet: powerpc--netbsd GCC target triplet: powerpc--netbsd http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43135