Reputation: 73
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++
Upvotes: 7
Views: 1325
Reputation: 48998
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;
Upvotes: 8
Reputation: 85827
The language expects a type in Foo< ... >
. What you're providing is an "incomplete type" (bar
isn't defined yet), but that's fine because T
isn't actually used anywhere in your template.
C++ allows the syntax class bar
to refer to a class bar
for compatibility with C, where you had to say struct bar
to refer to a type defined as struct bar { ... };
. In C++, the struct
/class
keyword is optional if the compiler already knows that bar
is a class.
class bar()
and class bar(int a)
are function types. They mean bar ()
and bar (int)
respectively, i.e. a function (taking no arguments / taking an int
) returning a bar
.
Upvotes: 0