简体   繁体   中英

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

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++

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, ie 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;

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, ie a function (taking no arguments / taking an int ) returning a bar .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM