Topic: When are templates instantiated?


Author: leif.lonnblad@thep.lu.se (Leif Lonnblad)
Date: Wed, 11 May 2005 20:58:48 GMT
Raw View
I have appedned a piece of code below, which relies on the fact that a
templated function is not instantiated until the point where it is
actually used. Or so I thought. The code compiled fine with gcc until
version 3.4.3, but on 4.0.0 it fails.

The error message complains that the struct foo is an undefined type at
(1). However, at the point where that function is actually used at (2),
and hence should be instantiated, the struct foo is defined.

I tried it on the Comeau online compiler, and there the code compiles
for versions 4.2.43 and below, but fails on versions 4.2.44 and above. I
guess that since both gcc and Comeau has changed their behavior, it is
to make things more standard compliant. But I haven't been able to find
where the standard mandates this behavior. Any thoughts?

Leif L=F6nnblad



    struct foo;

    template <int I>
    struct bar {

      inline void test(const foo & f) { f.test(); } // (1)

    };

    struct foo {
      void test() const {}
    };

    int main () {
      bar<0> b;
      b.test(foo()); // (2)
    }



---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: AlbertoBarbati@libero.it (Alberto Barbati)
Date: Thu, 12 May 2005 05:56:36 GMT
Raw View
Leif Lonnblad wrote:
> I have appedned a piece of code below, which relies on the fact that a
> templated function is not instantiated until the point where it is
> actually used. Or so I thought. The code compiled fine with gcc until
> version 3.4.3, but on 4.0.0 it fails.
>=20
> The error message complains that the struct foo is an undefined type at
> (1). However, at the point where that function is actually used at (2),
> and hence should be instantiated, the struct foo is defined.
>=20
> I tried it on the Comeau online compiler, and there the code compiles
> for versions 4.2.43 and below, but fails on versions 4.2.44 and above. =
I
> guess that since both gcc and Comeau has changed their behavior, it is
> to make things more standard compliant. But I haven't been able to find
> where the standard mandates this behavior. Any thoughts?

>    struct foo;
>
>    template <int I>
>    struct bar {
>      inline void test(const foo & f) { f.test(); } // (1)
>    };
>
>    struct foo {
>      void test() const {}
>    };
>
>    int main () {
>      bar<0> b;
>      b.test(foo()); // (2)
>    }

Comeau 4.2.44 and gcc 4.0.0 are right. Non-dependent names are bound at
point they are used (=A714.6.3). In your specific case, f.test() has to b=
e
bound immediately at the point of definition of the template and not be
deferred to the point of instantiation.

Only if the expression had involved dependent names the binding would be
deferred, as in:

   template <int I> struct foo;

   template <int I>
   struct bar {
     inline void test(const foo<I> & f) { f.test(); } // (1)
   };

   template <int I> struct foo {
     void test() const {}
   };

   int main () {
     bar<0> b;
     b.test(foo()); // (2)
   }

now foo<I> is a dependent name, so f.test() is resolved at the point of
instantion.

HTH,

Alberto

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]