problems with template instantiation

John McCurry john.mccurry@talk21.com
Tue Aug 22 07:13:00 GMT 2000


Hi folks,

I expect this to be a trivial problem for someone who has more
experience with the GNU compiler than I do.
The problem is that I can't get the compiler to automatically create the
required instantiations of template
classes (which I think it should do). I hope the following example will
illustrate the point:

I have built a trivial application from the 3 files: a.h, a.cxx and
main.cxx

FILE a.h:

    template <class T> class A
    {
    public:
        A();
        A(const T& t);
        ~A();
        T getValue() const;

    private:
        T value;
    };

<EOF>


FILE a.cxx:

    #include "a.h"

    template <class T> A<T>::A() {}
    template <class T> A<T>::A(const T& v) { value = v; }
    template <class T> A<T>::~A() {}
    template <class T> T A<T>::getValue() const { return value; }

<EOF>


FILE main.cxx:

    #include <iostream.h>
    #include "a.h"

    int main()
    {
        A<double> a1(3.21);
        A<int> a2(3.21);

        cout << "values = " << a1.getValue() << ", " << a2.getValue() <<
endl;

        return 0;
    }

<EOF>

I have compiled the source files with the usual "g++ -o file.o -c
file.cxx " (g++ version egcs-2.91.66) and tried to link with:

/usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66/collect2 -m elf_i386
-dynamic-linker /lib/ld-linux.so.2 /usr/lib/libg++.so.2.7.2
    -L. -L/usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66 -Bdynamic
/usr/lib/crt1.o /usr/lib/crti.o /usr/lib/crtbegin.o main.o a.o
    /usr/lib/crtend.o /usr/lib/crtn.o -lstdc++ -lc -lm -o test

This generates the following output which indicates that the necessary
template classes (int, double) have not been instantiated in the object
code (or if they have, the linker cannot see them).

main.o: In function `main':
/home/src/template-example/main.cxx:6: undefined reference to
`A<double>::A(double const &)'
/home/src/template-example/main.cxx:7: undefined reference to
`A<int>::A(int const &)'
/home/src/template-example/main.cxx:9: undefined reference to
`A<int>::getValue(void) const'
/home/src/template-example/main.cxx:9: undefined reference to
`A<double>::getValue(void) const'
/home/src/template-example/main.cxx:11: undefined reference to
`A<int>::~A(void)'
/home/src/template-example/main.cxx:11: undefined reference to
`A<double>::~A(void)'
/home/src/template-example/main.cxx:11: undefined reference to
`A<int>::~A(void)'
/home/src/template-example/main.cxx:11: undefined reference to
`A<double>::~A(void)'
collect2: ld returned 1 exit status
make: *** [test] Error 1


However, if I add explicit declarations "template class A<double>",
"template class A<int>" to the end of a.h then everything works OK.

Surely, this cannot be the way that templates must be treated in order
to get egcs to compile the code!?
The code in the example should compile and link without this bizarre
hack (it would under Solaris `CC') and I should be grateful for any
advice or comments on how this could be achieved with g++. Of course, if
it appears that I am doing something wrong I would also be grateful if
you could point it out.

Thanks,

John McCurry




More information about the Gcc mailing list