Why is there not an std::is_struct type trait?

It returns true for both classes and structs. I know that in C++ they are almost the same thing, but I'd like to know why there's not a distinction between them in the type trait.

Unfortunately this is a common misconception in C++. Sometimes it comes from fundamental misunderstanding, but at other times it comes from an ambiguity in English. It can come from inaccurate compiler diagnostics, badly-written books, incorrect SO answers…

You've probably read something like this:

"There is no difference in C++ between a struct and a class except the default visibility of members and bases."

This passage can be interpreted in a sense that is misleading, because the notions of identity and equality are hard to distinguish when using phrases like "no difference".

In fact, C++ has not had structs since 1985. It only has classes.

The kind of types that you declare with the keyword class and the keyword struct are classes. Period. The keyword struct, and the visibility rules that are the default when defining a class using that keyword, were kept only for backward compatibility with C … but that's a syntax thing. It doesn't make the resulting types actually be of a different kind.

The type trait makes no distinction because there literally isn't one to make.


It is impossible to distinguish a difference in semantics for empty definitions like

class C {
public:

};

from

struct S {

};

or similarly

class C {

};

and

struct S {
private:

};

Apart from the struct vs class keyword, there is no behavioral difference detectable. See also this Q&A.

Note: As remarked by @KyleStrand, derivation also requires explicit access specifiers, so S : private Base {}; and C : Base {}; are equivalent, the same as S : Base {}; and C : public Base {};, where S is a struct, C is a class, and Base can be either.


They're the same thing. The only difference (default member visibility) exists only at compile time. There is otherwise no difference at all between struct and class.

ETA: What you probably want is std::is_pod, which will tell you if your class is a "plain old data type". Much of the discussion and commentary on this question seems to indicate that this is what those who think there should be a distinction actually want.