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++
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.
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.
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.
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).
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;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With