Template template parameter argument names usage

2020-08-04 05:03发布

问题:

In the code

template < template<class TTP> class TP > ... // whatever

is TTP usable anywhere at all then? Can't find any reference to what happens with these names in the Standard.

回答1:

[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.

It can be used inside that list, and that's it. 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;


回答2:

You can access it, you just have to be slightly indirect about it.

                        /--- don't bother giving this a name.
                        |
                        |             Put it here instead ------------------\                                 |
                        |                                                   |
                        V                                                   V
template<template<typename, typename ...> class container_tmpl, typename value_t>
void foo(container_tmpl<value_t> x) {
    std:: cout << __PRETTY_FUNCTION__ << std:: endl;
}

More precisely, if you have an object of type vector<int> and you pass it to foo above, then foo can access the relevant type parameters:

vector<int> v;
bar(v);

When bar(v) is called, then bar "knows" the first parameter, which (I think?) is your goal.

I'm not saying the other answers are incorrect, it's just that you asked slightly the wrong question.

To understand the answer I've given, it's probably easier to forget about the template line and instead look at:

/* complex template-template gibberish */
void foo(container_tmpl<value_t> x) {

The type of x, the parameter to foo, is of type container_tmpl<value_t>. Where container_tmpl is something like vector or list, and value_t is something like int or std::string. Once you write this signature, it's obvious that value_t is simple a type (and hence becomes typename value_t in the template introduction) and that container_tmpl is a template taking (at least) one type parameter.

In this context, value_t and container_tmpl are defined inside bar.

If you don't understand why I have typename ..., then remember that vector actually takes two type args, not one. Anyway, the basic idea is that you must provide names for these template args outside where you would expect to get them. E.g. if you have a template that takes three arguments, two type parameters and an integer.

template< template<typename,int,typename> class the_template, typename T1, int I, typename T2>
void foo(the_template<T1,I,T2> x);


回答3:

No. It's a template parameter for TP<>, not the outer template function.