0

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.

vines
  • 5,160
  • 1
  • 27
  • 49
  • I wonder why you're asking. Is it so that you can capture `container` where `container` is something like `vector` or `list` and `value` is `int` or `std::string`? – Aaron McDaid Feb 15 '15 at 12:55
  • @AaronMcDaid Exactly! And I wanted to avoid the ` ...>` thing. – vines Feb 15 '15 at 12:59
  • I've done that before, but I can't quite remember. I'm pretty sure it's straightforward. I'm trying now – Aaron McDaid Feb 15 '15 at 13:24
  • @AaronMcDaid Yep, I got it working and just wondered if it can be refined any further -- have never used the template template args before :) – vines Feb 15 '15 at 13:27
  • I've added such an answer. We might need to edit the question at some point - your real question is subtly different from what you ask. Given a type `T`, which we know is of the form `container_template`, you want to get access separately to both `container_template` and `value_type`. – Aaron McDaid Feb 15 '15 at 14:04
  • ... actually, do you really need the `container_type` (to specialize on, or to put 'new' value_types into)? Or is it sufficient to simply get `value_type`? – Aaron McDaid Feb 15 '15 at 14:06
  • @AaronMcDaid https://ideone.com/rcbnV1 – vines Feb 15 '15 at 14:29
  • 1
    How about simply `template auto get_keys(const & T m) -> decltype(m.begin()->first)`? – Aaron McDaid Feb 15 '15 at 20:26
  • I've added another answer that answers your question more directly. Yes you can access it – Aaron McDaid Feb 16 '15 at 18:48

3 Answers3

2

[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;
T.C.
  • 133,968
  • 17
  • 288
  • 421
1

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);
Aaron McDaid
  • 26,501
  • 9
  • 66
  • 88
  • That's exactly what I did and wondered if it can be simplified somehow. But the question was really about the standard, which I'm not too strong in... By the way, I appreciate your suggestion regarding `decltype` and consider going that route instead of bloody variadic template templates! =) – vines Feb 16 '15 at 18:57
0

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

Blob
  • 561
  • 1
  • 6
  • 19