As we know, struct
and class
are interchangeable in many places in the language. Confusingly, the keywords themselves do not necessarily correspond to the language used in the standard. For example, in draft standard N4567 [class]/10,
A POD struct109 is a non-union class that is both a trivial class and a standard-layout class, and has no non-static data members of type non-POD struct, non-POD union (or array of such types). Similarly, a POD union is a union that is both a trivial class and a standard-layout class, and has no non-static data members of type non-POD struct, non-POD union (or array of such types). A POD class is a class that is either a POD struct or a POD union.
In over-simplified terms, struct
and class
are interchangeable in the following cases:
- declaration of a "class"
- declaration of a scoped enumeration type
- elaborated type specifier unless the "class" was declared with
union
However, struct
explicitly cannot be used in a template declaration to introduce type template parameters:
template <struct T> // error
I'm unable to see any significant difference between struct
and class
, even in the POD example above because a POD struct as defined in the standard can be declared with either struct
or class
.
[class]/8 A standard-layout struct is a standard-layout class defined with the class-key struct or the class-key class. A standard-layout union is a standard-layout class defined with the class-key union.
This seems rather redundant and confusing while introducing a glaring inconsistency.
I have two questions:
Are there any technical differences that I have missed that significantly distinguish
struct
andclass
?What is the rationale, if any, behind this clumsiness?
I'm ignoring the difference between default access specifiers because everyone knows that already.
struct
comes from C, and exists in C++ mainly for reasons of compatibility with the C programming language.The main difference between a
struct
and aclass
is that for thestruct
its members havepublic
access by default whereas for theclass
its members haveprivate
access by default.The keyword
class
used in template arguments does not define a class but rather a non type template argument and can be used interchangeably with keywordtypename
.As for why you can't use
struct
keyword for specifying a non type template argument, the reasons are historical and I guess you have to ask Bjarne for it :) or refer to this SO answer for info behind the scenes.A reason for existence of
struct
is for compatibility with C.Why then, did "C with Classes" introduce the new keyword
class
when you could usestruct
for the same thing, you may ask. See this SO answer for plausible speculation. In short, it's probably because there was desire for emphasis on OOP in which class is a widely used term. Only Stroustrup may know for certain.What needs to be understood, is that the concept of a class is not one and the same with the keyword
class
.There are three keywords for declaring classes. These keywords known as class-keys are
class
,struct
andunion
. The non-union classes that are declared with eitherclass
orstruct
are exactly the same thing, except for †. Union classes are different from non-union classes.C++ re-uses keywords for different purposes in different contexts.
class
keyword in a class declaration context, is not entirely the same asclass
keyword in a template argument definition. One keyword being equivalent to another in one context does not make it equivalent in all contexts. The reason for reusing keywords in different but similar contexts (static
is another example), is to avoid introducing new keywords, which introduces more holes with compatibility with C (or earlier C++ standard) that does not have the new keywords.The reason why
class
keyword was reused in the context of template type arguments was probably because classes are types, and therefore typically used as type parameters. There is also atypename
keyword, which was added later and is (almost) interchangeable withclass
in template type argument declaration, but also used elsewhere (dependent type names) whereclass
is not used. See this answer for a link and a summary about why a separate keyword was added to that context.Why
struct
is not used in the context as an equivalent, you may ask. Well, that's another question to Stroustrup or the committee. It's an opposite choice than what committee did whenenum class
/enum struct
was introduced.Good. There isn't any except for †
I see no inconsistency in the quote from the standard. I see redundancy and I suspect that the redundancy exists to make it extra clear that a class declared with the keyword
struct
is still a class.I've already answered, but to be clear, there is no difference between classes declared with
struct
andclass
keywords, beyond †.† the difference with the default access specifier (as you already know, and also described here), which is their only difference.