template instantiation problem with g++ 4.1

Egon Kocjan egon@krul.ath.cx
Tue Jan 9 13:45:00 GMT 2007


Ok, I have found a way to delay the lookups, so forward declarations are 
not needed. I just wonder, if there is a nicer way to do it, the 
solution looks like a compiler stress test :)

#include <vector>
#include <iostream>

template <class T>
struct yy { };

template <class T>
void y(const T &t)
{ yy<const T &>::y(t); }

template <>
struct yy<const int &> {
       static void y(const int &i)
       {
               std::cout << i << std::endl;
       }
};

template <class T>
struct yy_iter {
       static void y_iter(T begin, T end)
       {
               std::cout << "iter" << std::endl;
               for(; begin != end; ++begin)
                       y(*begin);
       }
};

template <class T>
struct yy<const std::vector<T> &> {
       static void y(const std::vector<T> &v)
       {
               std::cout << "vector" << std::endl;
               yy_iter<typename 
std::vector<T>::const_iterator>::y_iter(v.begin(), v.end());
       }
};

void x()
{
       std::vector<int>  q;
       q.push_back(5);
       std::vector<std::vector<int> > z;
       z.push_back(q);
       y(z);
}

int main()
{
       x();
}


prints:

vector
iter
vector
iter
5


Egon Kocjan wrote:
> Hello,
>
> I have some code, which compiles with g++ 3.2-4.0 and msvc 7.x-8.x. It 
> does not compile with the latest g++ 4.1.1. Example:
>
> #include <vector>
>
> inline void y(int i)
> {
> }
>
> template <class T>
> void y_iter(T begin, T end)
> {
>        for(; begin != end; ++begin)
>                y(*begin);
> }
>
> template <class T>
> void y(const std::vector<T> &v)
> {
>        y_iter(v.begin(), v.end());
> }
>
> void x()
> {
>        std::vector<std::vector<int> > z;
>        y(z);
> }
>
> I get this error:
> x.cpp: In function âvoid y_iter(T, T) [with T = 
> __gnu_cxx::__normal_iterator<const std::vector<int, 
> std::allocator<int> >*, std::vector<std::vector<int, 
> std::allocator<int> >, std::allocator<std::vector<int, 
> std::allocator<int> > > > >]â:
> x.cpp:17:   instantiated from âvoid y(const std::vector<T, 
> std::allocator<_CharT> >&) [with T = std::vector<int, 
> std::allocator<int> >]â
> x.cpp:23:   instantiated from here
> x.cpp:11: error: cannot convert âconst std::vector<int, 
> std::allocator<int> >â to âintâ for argument â1â to âvoid y(int)â
>
> It seems as if symbol resolving has moved from template instantiation 
> to template definition time (just like "normal" functions). Is there a 
> way to avoid this issue for such recursive template instantiations? I 
> have a lot of code that depends on this approach...
>
> Thanks,
> Egon Kocjan



More information about the Gcc-help mailing list