4

I've recently started using C++ 11 a little bit more and have a few questions on special uses of the class keyword. I know it's used to declare a class, but there's two instances I have seen that I don't understand:

Method<class T>();

and

class class_name *var;

Why do we precede the typename by the keyword class in the first example, and what does the keyword do the pointer in the second example?

Dylan Lawrence
  • 1,503
  • 10
  • 32

2 Answers2

11

That is known as an elaborated type specifier and is generally only necessary when your class name is "shadowed" or "hidden" and you need to be explicit.

class T
{
};

// for the love of god don't do this
T T;
T T2;

If your compiler is smart, it will give you these warnings:

main.cpp:15:5: error: must use 'class' tag to refer to type 'T' in this scope
    T T2;
    ^
    class 
main.cpp:14:7: note: class 'T' is hidden by a non-type declaration of 'T' here
    T T;
      ^

If your class is not previously defined, it will also act as a forward declaration.

For example:

template <typename T>
void Method()
{
    using type = typename T::value_type;
}

Method<class T>(); // T is a forward declaration, but we have not defined it yet, 
                   // error.

Otherwise it's not necessary.

class T
{
public:
    using value_type = int;
};

// method implementation...

Method<T>();
Method<class T>(); // class is redundant here
user4112979
  • 312
  • 3
  • 11
2

In addition to other answers, you can you class keyword to forward declare a class in the usage spot. E.g. instead of:

class SomeClass;
SomeClass* p = some_function();

You can write:

class SomeClass* p = some_function();

This is often used with templates and tag dispatching, when instantiating a template requires a tag type argument whose only purpose is to make the instantiation a unique type and the tag does not have to be a complete type. E.g.:

template<class Tag> struct Node { Node* next; };

struct Some : Node<class Tag1>, Node<class Tag2> {};
Maxim Egorushkin
  • 131,725
  • 17
  • 180
  • 271
  • They are [not quite equivalent](http://stackoverflow.com/questions/24423481/a-class-name-introduced-inside-a-class-is-not-treated-as-a-nested-class-name). – T.C. Oct 06 '14 at 13:16
  • 1
    @T.C. They are equivalent in the examples I provided. – Maxim Egorushkin Oct 06 '14 at 13:20
  • 2
    Not if the code block is located in a class definition. – T.C. Oct 06 '14 at 13:22
  • @T.C. In a class definition both forms declare `SomeClass` to be in the scope of the enclosing class, is that right? – Maxim Egorushkin Oct 06 '14 at 13:32
  • 2
    No, first one puts `SomeClass` in the scope of the enclosing class. Second one puts it in the smallest enclosing namespace or block scope. (i.e., in the first one `SomeClass` would be a nested class. In the second it won't.) – T.C. Oct 06 '14 at 13:37