4

I have this code:

template <typename A> class templatedclass { public: using type = templatedclass; }; template <typename A> class sinkstuff { public: void print() { cout << "generic sinkstuff"; } }; template <typename A> class sinkstuff <templatedclass<A>> { public: void print() { cout << "partiallyspecialized sinkstuff"; } }; template <typename NtoA> struct pass_parameter : sinkstuff<typename templatedclass<NtoA>::type> {}; int main() { pass_parameter<int> obj; obj.print(); cout << is_same<templatedclass<int>, typename templatedclass<int>::type>::value; // 1, yes } 

I always thought the "using directive" was a typedef on steroids. How come I can use "templatedclass<int>::type" without specifying the parameter again, i.e. "templatedclass<int>::type<int>" ?

Isn't "using type = templatedclass" just a textual substitution? Am I missing something?

4
  • 1
    Nothing except macros are "just a textual substitution"! Commented Oct 4, 2014 at 17:40
  • Related: stackoverflow.com/q/25549652 Commented Oct 4, 2014 at 17:51
  • Related/duplicate: stackoverflow.com/q/8031823 Commented Oct 4, 2014 at 17:52
  • @dyp Definitely not duplicates but, yes, related. Commented Oct 4, 2014 at 17:55

2 Answers 2

4

The name of a class is "injected" into the class, this is called the injected-class-name. It is similar to:

class my_class_name { public: typedef ::my_class_name my_class_name; }; 

(But this of course doesn't compile, a class may not have a manually declared member of the same name as the class.)

Class templates also have an injected-class-name, and it can be used to refer to the class template itself, or the current specialization (including the current template arguments), depending on the context:

[temp.local]/1

Like normal (non-template) classes, class templates have an injected-class-name. The injected-class-name can be used as a template-name or a type-name. When it is used with a template-argument-list, as a template-argument for a template template-parameter, or as the final identifier in the elaborated-type-specifier of a friend class template declaration, it refers to the class template itself. Otherwise, it is equivalent to the template-name followed by the template-parameters of the class template enclosed in <>.

Sign up to request clarification or add additional context in comments.

Comments

2

This doesn't have anything to do with the using directive. Within the definition of A<T> (and the using directive is in that scope), saying A is the same as saying A<T>.

It's the same reason you may write:

template <typename T> struct A { void foo(const A&); }; 

instead of

template <typename T> struct A { void foo(const A<T>&); }; 

For more information, search for "injected-class-name".

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.