This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug c++/15631] New: Template instantiation can't see functions defined after template declaration.
- From: "msharov at talentg dot com" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: 24 May 2004 14:47:09 -0000
- Subject: [Bug c++/15631] New: Template instantiation can't see functions defined after template declaration.
- Reply-to: gcc-bugzilla at gcc dot gnu dot org
Consider the following code, where the intent is to allow
definition of function size_of for an arbitrary type. The
first ns1 section is in a library and the rest is in the
application.
----------------------------------------------------------
namespace ns1 {
int size_of (int) { return (sizeof(int)); }
int size_of (float) { return (sizeof(float)); }
}
namespace ns2 {
class foo {
public:
template <typename T>
inline void print (const T& x) { ns1::size_of(x); }
};
class derived : public foo {
public:
class A {
public:
A (float y) : m_y (y) {}
int size (void) const { return (ns1::size_of(m_y)); }
private:
float m_y;
};
public:
inline derived (float x) : m_a (x) {}
void print_derived (void);
private:
A m_a;
};
}
namespace ns1 {
int size_of (const ns2::derived::A& v) { return (v.size()); }
}
namespace ns2 {
void derived::print_derived (void) { print (m_a); }
}
int main (void)
{
ns2::derived f (.5);
f.print_derived();
return (0);
}
namespace ns1 {
int size_of (int) { return (sizeof(int)); }
int size_of (float) { return (sizeof(float)); }
}
namespace ns2 {
class foo {
public:
template <typename T>
inline void print (const T& x) { ns1::size_of(x); }
};
class derived : public foo {
public:
class A {
public:
A (float y) : m_y (y) {}
int size (void) const { return (ns1::size_of(m_y)); }
private:
float m_y;
};
public:
inline derived (float x) : m_a (x) {}
void print_derived (void);
private:
A m_a;
};
}
namespace ns1 {
int size_of (const ns2::derived::A& v) { return (v.size()); }
}
namespace ns2 {
void derived::print_derived (void) { print (m_a); }
}
int main (void)
{
ns2::derived f (.5);
f.print_derived();
return (0);
}
----------------------------------------------------------
Compilation of this produces:
test.cc: In member function `void ns2::foo::print(const T&) [with T =
ns2::derived::A]':
test.cc:37: instantiated from here
test.cc:11: error: no matching function for call to `size_of(const
ns2::derived::A&)'
test.cc:2: note: candidates are: int ns1::size_of(int)
test.cc:3: note: int ns1::size_of(float)
The size_of override for ns2::derived::A is defined after the declaration
of template print, but before its instantiation in print_derived, so the
compiler should have been able to see the new size_of at the point of
instantiation.
The workaround is to add "using namespace ns1;" after the first
namespace ns1 block and use size_of instead of ns1::size_of in the print
template. This suggests that during instantiation, only global overrides
are checked. The global overrides are also the only ones mentioned in the
"C++ misunderstandings" on the two stage name lookup.
--
Summary: Template instantiation can't see functions defined after
template declaration.
Product: gcc
Version: 3.4.0
Status: UNCONFIRMED
Severity: normal
Priority: P2
Component: c++
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: msharov at talentg dot com
CC: gcc-bugs at gcc dot gnu dot org
GCC host triplet: i686-gnu-linux
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=15631