Repository + nested templates doesn't work

Brent Casavant bcasavan@skywalker.ecn.ou.edu
Mon Jan 17 20:02:00 GMT 2000


Hello,

Please find attached a test program which demonstrates that g++ is
unable to handle a templated class which is used in another templated
class. This is true whether the nested class instance is a member or is
used as an automatic variable inside a method of the container class.

This appears to be a problem only with the template repository, as it
is possible to manually instantiate the templated class and successfully
link the executable. This is not an option in the "real code" I am working
on though because it is not known ahead of time what types of templated
parameters will be used later in the project.

It also appears that the nested template method will be successfully
"linked" if it is declared and implemented inline. That would work for
this trivial function, but again is not suitable for a full-scale
project.

This has been reproduced on:

	FreeBSD 3.1-STABLE with g++ version 2.95 19990728 (release)
	IRIX 6.5.4m with g++ version 2.91.66 19990314 (egcs-1.1.2 release)

Of course I don't necessarily expect the template repository to work on
IRIX since the MIPSpro ld must be used to generate usable code. But the
FreeBSD version should presumably work.

The program was compiled like this and produced the messages:

% /usr/local/bin/g++ -c -frepo tTemplates.cpp
% /usr/local/bin/g++ -frepo tTemplates.o
collect: recompiling tTemplates.cpp
collect: relinking
tTemplates.o: In function `User<int>::User_Method(void) const':
tTemplates.o(.text+0x9e): undefined reference to `Contained<int>::Contained_Method(void) const'
collect2: ld returned 1 exit status

This code has been confirmed to compile and link and run properly with
IRIX 6.5.4m and MIPSpro 7.30 C++ compilers.

Thanks for your time. When I have opportunity I'll try to look at the g++
template repository code myself, but as I'm not a "compiler guy" I think
my chances are pretty slim.

Thanks,
Brent Casavant

/* tTemplates.cpp: Shows problems with nested templates in g++.
 *
 * Compile with:
 *     g++ -c -frepo tTemplates.cpp
 *     g++ -frepo tTemplates.o
 */
#include <iostream.h>

/************************************************************
 * Contained: An instance of this will appear in class User *
 ************************************************************/

template <class DataType>
class Contained
{
    public:
    	Contained(const DataType& data) : mData(data) { };
        void Contained_Method(void) const;

    protected:
        DataType mData;
};

/* If Contained_Method is inlined then it is resolved and all is fine */
template <class DataType>
void
Contained<DataType>::Contained_Method(void) const
{
    cout << "The answer is: " << mData << endl;
}

/*************************************************
 * User: Contains an instance of class Contained *
 *************************************************/

template <class DataType>
class User
{
    public:
        User(const DataType& data)
        { mpContained = new Contained<DataType>(data); };
    ~User(void) { delete mpContained; };
        void User_Method(void) const;

    protected:
        Contained<DataType>*    mpContained;
};

template <class DataType>
void
User<DataType>::User_Method(void) const
{
    if (mpContained)
        mpContained->Contained_Method();
    else
        cout << "mpContained is NULL" << endl;
}

/***********************************
 * main: To get everything rolling *
 ***********************************/

int main(void)
{
    User<int>   user(2*3*7);
    user.User_Method();
    return 0;
}

-- 
Brent Casavant (b.j.casavant@ieee.org)
http://reality.sgi.com/bcasavan
-.- -.. ..... . -- -...



More information about the Gcc-bugs mailing list