This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug c++/15631] New: Template instantiation can't see functions defined after template declaration.


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]