Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there any use for named parameters into template template parameters

If I need to define a template foo function with a template-template parameter, I usually do the following:

// Notice that the template parameter of class T is unnamed.
template <template <typename> class T> void f() { std::cout << "Yay!\n"; }

Notice that the template parameter of the template-template parameter is unnamed, but we can assign a name to this parameter:

// Now the template parameter of class T is named INNER.
template <template <typename INNER> class T> void f(const INNER &inner)
{ std::cout << inner << " Yay!\n"; }

This doesn't seems to be usefull at all, because I cannot reffer the INNER parameter in the function, the code above produces the following error:

error: 'INNER' does not name a type

It surprises me that the typename INNER doesn't name a type, after all the typename keyword is there in order to naming a type. Anyway, this is easy to fix though:

// Now INNER is the name of the template parameter of class T and also
// the name of the second template parameter of foo.
template <template <typename INNER> class T, typename INNER> void f(const INNER &inner)
{ std::cout << inner << " Yay!\n"; }
// ...
f<std::valarray, int>(666); // Prints "666 Yay!"

But in the end, the INNER parameter doesn't need a name after all:

// Now the template parameter of class T is unnamed one more time,
// INNER is the name of the second template parameter of foo.
template <template <typename> class T, typename INNER> void f(const INNER &inner)
{ std::cout << inner << " Yay!\n"; }
// ...
f<std::valarray, int>(666); // Prints "666 Yay!"

And (sure you already noticed before me) the name in the parameter of the template-template parameter is ignored! It sure have been ignored because if not it should have a name-clash with the second template parameter of foo, doesn't it?

Another demonstration of the name of the parameter of the template-template parameter being ignored:

// Now T is the name of the template parameter of class T and also
// the name of the template parameter of foo!
template <template <typename T> class T> void f()
{ std::cout << "Yay!\n"; }
// ...
f<std::valarray>(); // prints "Yay!"

The type named T is being used by the template-template parameter and by the template-template itself at the same time? I don't think so, the name into the template-template parameter is ignored AFAIK.

So, what's the question?

  1. Are my guess correct? The names of named template parameters of template-template parameters are ignored?
  2. If I'm mistaken and I've misunderstood the whole thing, there's a use for the named parameters into the template-template parameters? Can you provide some useful examples?

As for useful examples on #2 i'm referring to something that only could be achieved using the named template parameters of template-template parameters.

like image 782
PaperBirdMaster Avatar asked Mar 11 '15 16:03

PaperBirdMaster


1 Answers

[basic.scope.temp]/p1:

The declarative region of the name of a template parameter of a template template-parameter is the smallest template-parameter-list in which the name was introduced.

(Now try saying that 10 times.)

It can be used inside that list. For instance,

template < template<class T, T t> class TP > class foo {};
//                           ^  ^-----T's scope ends here
//                           |
//                           T can be used here

foo<std::integral_constant> bar;
like image 99
T.C. Avatar answered Nov 15 '22 13:11

T.C.