1

I need a template-of-template class, but the issue is, that I can't access the type of nested template:

template<template<class TParamPayload> class TMsg>
class ParameterBasedFilter : public IMsgFilter
{
public:
    typedef TMsg<TParamPayload> ExpectedMessage;
    typedef TParamPayload::otherType SomeOtherType;
};

And here is a usage (I want to pass only one template argument, without comma)

ParameterBasedFilter<SomeMessage<SomePayload>> filter;

There is an error inside ParameterBasedFilter:

error: 'TParamPayload' was not declared in this scope
typedef TMsg<TParamPayload> ExpectedMessage;
             ^

Is it possible at all to get the nested template type? I know, that code below will work

template<class TParamPayload, template<class> class TMsg>
class ParameterBasedFilter : public IMsgFilter
{
public:
    typedef TMsg<TParamPayload> ExpectedMessage;
    typedef TParamPayload::otherType SomeOtherType;
};

but then I have to pass 2 types to the template arguments:

ParameterBasedFilter<SomePayload, SomeMessage<SomePayload>> filter;

and it looks weird, because SomePayload is used twice.

yudjin
  • 349
  • 5
  • 14
  • 1
    Possible duplicate of [Where and why do I have to put the “template” and “typename” keywords?](http://stackoverflow.com/questions/610245/where-and-why-do-i-have-to-put-the-template-and-typename-keywords) – πάντα ῥεῖ Jan 15 '15 at 10:51
  • I don't think this is a duplicate (at least not of the referred to question). The OP is asking why he cannot refer to the (named) template parameters of a template template parameter, i.e. `TParamPayload` (jeez.. did anyone get that?). – JorenHeit Jan 15 '15 at 12:02

2 Answers2

3

Perhaps you're looking for partial specialization? That would allow the original syntax mentioned in your question:

template <typename> class ParameterBasedFilter;

template <template<class> class TMsg, typename TParamPayload>
class ParameterBasedFilter<TMsg<TParamPayload>> : public IMsgFilter
{
public:
    typedef TMsg<TParamPayload> ExpectedMessage;
    typedef TParamPayload::otherType SomeOtherType;
};

Usage is simple:

ParameterBasedFilter<SomeMessage<SomePayload>> filter;
Columbo
  • 60,038
  • 8
  • 155
  • 203
  • Definately the solution when he wants the type passed to `ParameterBasedFilter` to be of the form `TMsg`. Otherwise, just use a regular `template `. – JorenHeit Jan 15 '15 at 12:08
  • @JorenHeit What do you mean? – Columbo Jan 15 '15 at 12:10
  • If he just wants the usage case to work, he might as well use `template ` (your unspecialized case). However, to get the nested type he would have to make sure there is a nested `typedef` that defines the payload argument, so your solution is better :-) (would work for all STL-like containers though). – JorenHeit Jan 15 '15 at 12:14
  • @JorenHeit You mean, wouldn't work for STL-like containers? Well, in that case one could use a variadic template template parameter. – Columbo Jan 15 '15 at 12:16
  • Haha no, not what I meant. What I meant was, if the `TMsg` class defines the equivalent of STL's `value_type` (thus defining `TParamPayload`), it would be possible to get the type like that without specializing. That said, your solution is probably more general and elegant. – JorenHeit Jan 15 '15 at 12:19
2

No, you cannot. However you will should to pass

ParameterBasedFilter<SomePayload, SomeMessage> filter;

SomePayload will not be used twice. Also, you should use typename when access to otherType

typedef typename TParamPayload::otherType SomeOtherType;
ForEveR
  • 55,233
  • 2
  • 119
  • 133