1

I was trying to convince a friend that struct is just a class in the modern C++. After a lot of arguing and resource exchange (including some SO Q&A), I came into an idea to prove it through code, so I wrote:

class A {};
struct B {};

int main()
{
    cout << (is_class<A>::value ? "Yes" : "No") << "\n";  // output Yes
    cout << (is_class<B>::value ? "Yes" : "No") << "\n";  // output Yes

    cout << (is_same<A,B>::value ? "Yes" : "No") << "\n"; // output No ???
}

As you can see, I was surprised from the third cout line output. So, I am stuck here now, and I do not know if am I right or not.

Is a struct a class or not?
Why does the code show two different things?

Update:

I pretty understand what is the difference between struct and class. What confused me is the difference between the is_class and is_same as answers showed. What should I have done if not asking here??? What is this site for? Why some users tend to claim questions are not useful without even put a comment to specify where it is not conforming with the asking policy?

Remember, We not all people speaks English fluently. and not all people have years of the experience.

Thanks for all who answer or comment.

Kamal Zidan
  • 474
  • 2
  • 9

3 Answers3

9

At first, you are right. a struct is just a class under the hood.

Some indications:

1- You can forward declare one of them and then define it with the other one (although some compliers may issue a warning).

class A;     // declaration of A with class
struct A { /* definition of A with struct */ } ;

2- is_class<> returns true for both.
3- There is no is_struct<> in <type_traits>.
4- In most cases, the two keywords are interchangeable. (e.g: in scoped enum).

However, they have important syntactic differences:

struct

  • Grants public access to its members by default.
  • Backward compatible with C if used without C++ features.

class

  • Grants private access to its members by default.
  • Not compatible with C.

Which one to use is a matter of convention and/or convenience.

Generally, I prefer using struct as an aggregate of data (record). And class for other uses.

Now we come to your second question:

Why does the code show two different things?

It does not.

Because is_class<> is not about types but rather it is about type categories. (i.e. is_class<x> checks if the type x is a class or not) whereas is_same<> is about types themselves ((i.e. is_same<x, y> checks if type x is as same as type y or not))

If you change struct in your test code into class, is_same<> would still outputs “No” because A is a type and B is another type even if they both have the same type category which is class.

Based on your code:

A a;  // a is of type A
B b; // b is of type B
// Can we say that a and b of the same type?
// No. And this is what is_same<> checks.
Shadi
  • 1,701
  • 2
  • 14
  • 27
7

You are confused as to what std::is_same<> is for.

From http://en.cppreference.com/w/cpp/types/is_same:

If T and U name the same type with the same const-volatile qualifications, provides the member constant value equal to true. Otherwise value is false.

Clearly A and B are different classes; with that last sentence I am implying that you are indeed correct in that a struct is the same as a class; the difference being that a struct has a default access of public for its members, whereas a class has a default of private instead.

Don't take my word for it, the C++ standard states the following in 10.1.7.3 Elaborated type specifiers [dcl.type.elab]:

[...] either the class or struct class-key shall be used to refer to a class declared using the class or struct class-key.

Reference: http://eel.is/c++draft/dcl.type.elab

user2296177
  • 2,807
  • 1
  • 15
  • 26
3

This has nothing to do with struct vs class.

cout << (is_class<A>::value ? "Yes" : "No") << "\n";  // output Yes

Yes, because A is a class.

cout << (is_class<B>::value ? "Yes" : "No") << "\n";  // output Yes

Yes, because B is also a class (it really is).

cout << (is_same<A,B>::value ? "Yes" : "No") << "\n"; // output No ???

No, because they're not the same class.

A and B are two different types.

It's std::is_same, not std::is_similar.

Community
  • 1
  • 1
Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
  • thanks @BoundaryImposition for your great posts. I checked them and they are really good. So, if I need to check such a thing I can use something like: `if (is_class(A) && (is_class(B))`. ... I looked for `is_similar`, but it is not there. so I guess you mention it for clarity. But what if I need such functionality? – Kamal Zidan May 19 '17 at 03:03
  • @KamalZidan: Yep. And yep `std::is_similar` doesn't exist; as far as I know there's no way (or reason) to implement it. – Lightness Races in Orbit May 19 '17 at 13:29