23
votes

Executing the following code:

#include <iostream>
#include <type_traits>

struct s_ref {
    int &foo;
};

struct s_ptr {
    int *foo;
};

int main(int argc, char *argv[])
{
    std::cout << "s_ref is_standard_layout:" << std::is_standard_layout<struct s_ref>::value << std::endl;
    std::cout << "s_ptr is_standard_layout:" << std::is_standard_layout<struct s_ptr>::value << std::endl;
    return 0;
}

results in:

s_ref is_standard_layout:0
s_ptr is_standard_layout:1

Based on the uses of standard layout (i.e.: "Standard layout types are useful for communicating with code written in other programming languages") this makes sense, but I'm not sure which is the rule that is violated:

A standard-layout class is a class (defined with class, struct or union) that:

  • has no virtual functions and no virtual base classes.

  • has the same access control (private, protected, public) for all its non-static data members.

  • either has no non-static data members in the most derived class and at most one base class with non-static data members, or has no base classes with non-static data members.

  • its base class (if any) is itself also a standard-layout class.

  • And, has no base classes of the same type as its first non-static data member.

Edit: the quote is from: http://www.cplusplus.com/reference/type_traits/is_standard_layout/, but http://en.cppreference.com/w/cpp/concept/StandardLayoutType is also similar.

3
What's the source of your quote?Cheers and hth. - Alf
@Cheersandhth.-Alf Probably cplusplus.com.Holt
Cppreference fixed.. (we definitely made the error, I wonder if the other guys copied ours). You could still argue that it was correct because it said scalar or class whose memeber is standard-layout. Reference types aren't scalar or class.Cubbi

3 Answers

23
votes

The point of the C++ standard's concept of a standard layout class is that an instance of such a class can be reliably accessed as or copied to bytes, which, as the C++11 standard notes in its §9/9, makes such a class

useful for communicating with code written in other programming languages

However, the C++ standard does not require a reference to use storage at all. It's not an object. You can't take its address. So it can't be (reliably) copied to bytes, or accessed as bytes. And so it's not compatible with the notion of standard layout classes.

In the formal,

C++11 §9/7:

A standard-layout class is a class that:
— has no non-static data members of type non-standard-layout class (or array of such types) or reference,

12
votes

I don't know where you got that quote from, but it misses out the relevant rule from the standard.

(N3337) [class]/7: A standard-layout class is a class that:

has no non-static data members of type non-standard-layout class (or array of such types) or reference,

— has no virtual functions (10.3) and no virtual base classes (10.1),

— has the same access control (Clause 11) for all non-static data members,

— has no non-standard-layout base classes,

— either has no non-static data members in the most derived class and at most one base class with non-static data members, or has no base classes with non-static data members, and

— has no base classes of the same type as the f irst non-static data member.108

11
votes

In n4140 you can read:

9 Classes (7.1)

A standard-layout class is a class that:

  • has no non-static data members of type non-standard-layout class (or array of such types) or reference,

[edit]

for further information on why class with references is not standard layout read this excelent answer: C++ Standard Layout and References