Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Forward Declaration of class as template param. Why does this work?

Tags:

c++

I have been playing around with some c++ template meta-programing and I have discovered situation which I think is rather peculiar. Let say I have the following class.

template<typename T>
class Foo{
};

Then later I found I use a foward declaration of a class (I am assuming that is what it is being treated as) as the template argument as so

Foo<class bar> bar1;

I also found that the following also compile fine.

Foo<class bar()> bar2;
Foo<class bar(int a)> bar3;

So my question is, why does this work. What is going on in all three cases.
According to the standard I can not declare a class at this point so this fails:

Foo<class bar{}> bar4

My original assumption was this just a forward declaration and you could actually declare a class at that pointer (which I could see possible uses for). However, you can not. So my second question what is the use of above? Is there any practical uses of it or is just a result of how c++ works that this is legal. One use I can see is you can use this to create tagging information on a type.

I am using the most recent version of g++

like image 462
Christopher Glynn Avatar asked Sep 01 '16 19:09

Christopher Glynn


People also ask

Can you forward-declare a template?

You can declare default arguments for a template only for the first declaration of the template. If you want allow users to forward declare a class template, you should provide a forwarding header. If you want to forward declare someone else's class template using defaults, you are out of luck! Save this answer.

Why do you use forward declaration?

A forward declaration tells the compiler about the existence of an entity before actually defining the entity. Forward declarations can also be used with other entity in C++, such as functions, variables and user-defined types.

Why does C need forward declaration?

Classes. In some object-oriented languages like C++ and Objective-C, it is sometimes necessary to forward-declare classes. This is done in situations when it is necessary to know that the name of the class is a type, but where it is unnecessary to know the structure.

Is forward declaration good practice?

The Google style guide recommends against using forward declarations, and for good reasons: If someone forward declares something from namespace std, then your code exhibits undefined behavior (but will likely work).


1 Answers

In all 3 cases, you are forward declaring the class bar, so you have to define it later one.


Foo<class bar> bar1;

This works because it is allowed to declare a class for the first time in a template argument, i.e. it is equivalent to

class bar;
Foo<bar> bar1;

Foo<class bar()> bar2;

This creates the class bar, just as before, and creates a function taking no parameters and returning a bar.


Foo<class bar(int a)> bar3;

This is really similar to the second one, just that here, it declares a function taking an int, instead of none. It is equivalent to

class bar;
Foo<bar(int)> bar3;
like image 58
Rakete1111 Avatar answered Oct 26 '22 22:10

Rakete1111