[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

G++ mishandles templates within templates



>Submitter-Id:	net
>Originator:	Andrew Sayers
>Organization:	
>Confidential:	no
>Synopsis:	G++ returns compilation errors on several (presumably) valid nested template classes
>Severity:	serious
>Priority:	medium
>Category:	c++
>Class:		rejects-legal
>Release:	4.0.2 20050725 (prerelease) (Debian 4.0.1-3) (Debian testing/unstable)
>Environment:
System: Linux nautilus 2.6.12.3 #1 Fri Jul 29 13:43:06 BST 2005 i686 GNU/Linux
Architecture: i686

	
host: i486-pc-linux-gnu
build: i486-pc-linux-gnu
target: i486-pc-linux-gnu
configured with: ../src/configure -v --enable-languages=c,c++,java,f95,objc,ada,treelang --prefix=/usr --enable-shared --with-system-zlib --libexecdir=/usr/lib --enable-nls --without-included-gettext --enable-threads=posix --program-suffix=-4.0 --enable-__cxa_atexit --enable-libstdcxx-allocator=mt --enable-clocale=gnu --enable-libstdcxx-debug --enable-java-gc=boehm --enable-java-awt=gtk --enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.4.2-gcj-4.0-1.4.2.0/jre --enable-mpfr --disable-werror --enable-checking=release i486-linux-gnu
>Description:

I'm not sure whether this is a single bug or a family of related ones, so I'm filing it as a single report for now.  I've not been able to find any precedent for this kind of code, but I expect at least one of the two error templates must be legal.

This bug is triggered when a template class is declared inside another template class, then defined outside it.  The following causes compilation errors for the first two nested templates, the final template provides a partial workaround:

template<int a>
class containing_template {
public:
        template<int b> class error1;

        template<int b> class error2;
private:
        template<int a1, int b> class workaround_backend;
public:
        template<int b> class workaround : public workaround_backend<a, b> {};
};

template<> template<int a, int b> class containing_template<a>::error1<b> {};
template<> template<int a> template<int b> class containing_template<a>::error2<b> {};
template<> template<int a, int b> class containing_template<a>::workaround_backend<a, b> {};

int main() { return 0; };

The containing template causes no problems.  The "error1" template causes the compiler to complain that:
	test.cpp:13: error: template parameters not used in partial specialization:
	test.cpp:13: error:         'a'
The second template causes the compiler to complain that:
	test.cpp:14: error: partial specialization 'containing_template<a>::error2<b>' does not specialize any template arguments

By my understanding of C++, these aren't partial specialisations, they're definitions.  I'm not sure why the compiler thinks otherwise.  For templates that actually are partial specialisitions, I've even seen the compiler complain that the specialisation doesn't exist when I try to instantiate it.  If the above code is valid but the general class of error isn't obvious from it, I can file a bug report on this other case.

>How-To-Repeat:
This error is triggered whenever I try to compile this code.
>Fix:
In this trivial case, the inner templates could be defined inside the containing template, however this is not always desirable or even possible for complex templates.

The workaround in the code will avoid the problem for fairly simple cases, but more complex cases seem to trigger bugs like these even with the workaround.  Again, I can try to verify this and report it if you like.

	- Andrew



Reply to: