-1

Shouldn't typename only be used in template function or template class? Why the expresion below is legal?What's the function of typename in the expresion below?

#define DECLARE(T)  using Request = typename T::Request;

I would be grateful for any hint on this question.

2 Answers2

1

This is to allow using such expression in a macro (like mentioned in the original post).

Macro cannot know if it is used with template type argument or not, but has to work in both. Since typename is required when working with a template, it makes sense to allow it in non-template code (where it can be ignored).

Your original code serves as the example of such usage (; at the end removed):

#define DECLARE(T)   using Request = typename T::Request

This macro work in both template and non-template code:

struct Container { using Request = int; };
struct A { DECLARE(Container); };
template<typename T>
struct B { DECLARE(T); };

Without typename, you would get compilation error for such code:

B<Container>();
  • Thank you.You are right.I thought over and over and tried on the online compiler(https://godbolt.org/z/XNBLik). I got this error indeed(`need 'typename' before 'T::REQUEST' because 'T' is a dependent scope`) while compiled without the `typename` .What does this error implie?What is "dependent scope"? –  May 24 '20 at 10:03
  • @John You should check [this](https://stackoverflow.com/a/613132/1143634) answer. It has a quote from the standard that gives the definition of it. Look for the "If a name has this property - that it can't be looked up until the actual template arguments are known - then it's called a dependent name". Then check quote from (14.6/2) there. –  May 24 '20 at 10:49
  • It's so kind of you.Thank you. –  May 24 '20 at 10:51
0

That your line is a macro, which is a directive to preprocessor to replace all the occurances of DECLARE(T) with using Request = typename T::Request;, at the same time replacing the type T with the supplied real-type. For example, if the compiler sees anywhere DECLARE(string), it will replace that with using Request = typename string::Request;.

Hack06
  • 963
  • 1
  • 12
  • 20
  • Thank you for the clarification.I could guess the result.But what's the function of `typename` in `#define DECLARE(T) using Request = typename T::Request;`? –  May 24 '20 at 09:10
  • 1
    The keyword ```using``` and ```typename``` here are used for aliases alongside templates. You can read more here: https://en.cppreference.com/w/cpp/language/type_alias – Hack06 May 24 '20 at 09:17