Should the template template parameters get the parameters allowed from the previous parameters?

I found a strange problem for g ++ 4.4 and 4.5. I asked about this because I thought I was making some kind of stupid mistake in the code. The original post is here , but for the sake of completeness I will revise the problematic code in question here:

$ cat templatetemplate.cc template <int i> struct LabelTypeMap { typedef int type_t; }; template <bool> struct Hold { typedef int type; }; template<typename Holder, template<typename Holder::type> class typeMap> struct Whatever { }; template <bool Enable> struct Now { typedef Whatever<Hold<ENABLE>, LabelTypeMap> concrete_t; }; Now<true>::concrete_t obj; $ g++ -DENABLE=Enable -c templatetemplate.cc templatetemplate.cc:11: error: type/value mismatch at argument 2 in template parameter list for 'template<class Holder, template<typename Holder::type <anonymous> > class typeMap> struct Whatever' templatetemplate.cc:11: error: expected a template of type ↡ 'template<typename Holder::type <anonymous> > class typeMap', got ↡ 'template<int i> struct LabelTypeMap' marcelo@macbookpro-1 :~/play$ $ g++ -DENABLE=true -c templatetemplate.cc (no error) 

Actually, this is not a programmer's mistake, although it is possible that I am missing some unclear rule for resolving a template of a template for a template. However, I tried to send an error to the ubuntu tracker (I hope they fire it or send an error message up)

So, just to check if this is really a mistake, I received a copy of the 2003 standard, and I read section 14.3.3 a couple of times, and yet I feel like I missed the slightest if I passed a template template with a parameter, as in the code example, it’s allowed or prohibited. I’m not even sure that something is mentioned in this part of the document.

My question is: do you know where this is indicated?

EDIT: It’s quite interesting that this question has remained unanswered for more than a week: it makes me think that the ISO C ++ standard does not indicate whether we can use the previous template parameter to indicate the types of subsequent template parameters (the least in the declared form), and it basically remains for developers to decide

2nd EDIT (01/10/2011): People, maybe there is something in this that we are all lacking (or many highly skilled compiler developers are wrong): I tried this with the intel C ++ XE 12.0 compiler, and I got this is:

  $icpc ttemplatetemplate.cc -o ./x2test templatetemplate.cc(12): error: class template "LabelTypeMap" is not compatible with template template parameter "typeMap" struct Now { typedef Whatever<Hold<Enable>, LabelTypeMap> concrete_t; }; ^ compilation aborted for templatetemplate.cc (code 2) $ icpc --version icpc (ICC) 12.0.0 20101116 Copyright (C) 1985-2010 Intel Corporation. All rights reserved. 
+4
source share
4 answers

I cannot find anything in the standard that prohibits it, although I tried this simple code (which, it seems to me, simplifies your problem) in Comeau :

 template<int> class A {}; template<class T, template<T> class U> class B {}; B<int, A> b; 

And it causes the following error:

"ComeauTest.c", line 4: error: a template template parameter the parameter cannot depend on the type of another template parameter

I would like to find which part of the standard actually prohibits it ...

+1
source

By the way, here is the solution I found in the main problem:

 template <int i> struct LabelTypeMap { typedef int type_t; }; template <bool> struct Hold { typedef int type; }; template<typename Holder> struct Whatever { typedef typename Holder::type HT; template <template <HT> class typeMap> struct Whatever2 { }; }; template <bool Enable> struct Now { typedef typename Whatever<Hold<Enable> >::Whatever2<LabelTypeMap> concrete_t; }; 

Using a nested template, I can enter typename via typedef .

+1
source

I suspect this strange construct: template<typename Holder::type> class typeMap What was it supposed to be? The typename Holder::type bit is strange; which should be a dummy name (identifier). Holder::type not even an identifier.

0
source

Shouldn't it be?

This is due to the fact that LabelTypeMap itself is a template (template template parameter) and, therefore, requires a type indication.

 template <bool Enable> struct Now { typedef Whatever<Hold<ENABLE>, LabelTypeMap<ENABLE> > concrete_t; }; 
-1
source

All Articles