B.2 — Long long, auto, decltype, nullptr, and enum classes

Type long long

If you recall from lesson 2.4 -- Integers, the largest integer type C++03 defines is “long”. Long has a platform-specific size that can be either 32 or 64 bits. C++ defines a new type named long long that’s guaranteed to be at least 64 bits in length. Because “long long” was already introduced by C99, many compilers already supported it prior to C++11.

C++11 also imported the 2.4a -- Fixed-width integers and the unsigned controversy from C99.

Type inference with auto and decltype

My favorite change in C++11 is the introduction of the auto keyword. Consider the common use case where you want to iterate through a vector using a for loop:

Having to determine that the data type for the iterator itr is “std::vector::const_iterator” is both a pain to get correct and obnoxious considering that the compiler already knows that the return type from cbegin() is std::vector::const_iterator -- but it makes you type it out anyway.

That’s where the auto keyword comes in:

The auto keyword tells the compiler to infer the type of the variable from its initializer.

The decltype can be used to determine the type of an expression at compile-type.

Although it may seem like auto and decltype will always deduce the same type, that isn’t the case, as shown by the following example:

Generally, if you need a type for a variable you are going to initialize, use auto. decltype is better used when you need the type for something that is not a variable, like a return type.

Type nullptr

In previous iterations of C and C++, 0 acted as both a constant integer and as the null pointer constant, which is why the following oddity occurs:

C++11 defines a new reserved identifier called nullptr (of type nullptr_t) that is not an integer, and can not be converted to an integer (though oddly enough, it can be converted to the boolean value false). 0 remains a valid null point constant for backwards compatibility purposes.

Enum classes

(Note: The following isn’t yet supported by Visual Studio 2010, but it’s simple enough to follow even without trying the examples yourself)

In C++03, enums are not type safe -- they are treated as integers even when the enumeration types are distinct. Consider the following case:

When C++ compares a and b, it’s comparing them as integers, which means in the above example, a does equal b since they both default to integer 0. This is definitely not as desired since a and b are from different enumerations!

C++11 defines a new concept, the enum class, which makes enums both strongly typed and strongly scoped.

With normal enums, you can access enumerators (eg. RED) directly in the surrounding scope (eg. within main). However, with enum classes, the strong scoping rules mean you have to use a scope qualifier to access the enumerator (eg. Color::RED). This helps keep name pollution and the potential for name conflicts down.

The strong typing rules means that C++ will look for an explicitly defined comparison function to compare Color and Fruit. Since we haven’t defined an operator==(Color, Fruit) function, the compiler won’t understand how to compare a and b in any meaningful way, and this will cause a compile-time error to occur.

B.3 -- Range-based for statements and static assert
B.1 -- Introduction to C++11

11 comments to B.2 — Long long, auto, decltype, nullptr, and enum classes

  • xiaoqi

    It’s help for me,

  • Matt

    I think the first word of the first paragraph should be "if" instead of "in".

  • tata

    Hi, it seems that the declaration of the overloaded subscript operator would be something like:

    If that is correct, does that mean that the last ("const") in the comment below is a typo?


    • tata

      sorry bad question, I’ve forgotten the meaning of const explained here:

  • rkedge

    There seems to be a quirk with VS10 that does not show up in g++. I’m using jGRASP with MinGW.

    regarding the enum code above:

    enum.cpp:16:13: warning: comparison between ‘enum main()::Color’ and ‘enum main()::Fruit; [-Wenum-compare]

    Seems like this desired behavior is already implemented here. The comparison is not allowed. I think I’m using C++98 because it won’t let me do range-based for loops.
    It also seems like it’s using namespaces (or something similar) to reduce the scope of the enums.

  • RevEng

    From the 7th paragraph in your narrative, above:
    The decltype can be used to determine the type of an expression at compile-type.

    Alex, is “compile-type” supposed to be “compile-time“?

  • cody

    I know this is nitpicking but - auto is not new. What is new is the definition of auto.

    It actually originally is in C (think carry over from B ?).

    As the C FAQ points out about the auto keyword :
    “One can imagine stylistic uses such as emphasizing that a variable must be automatic, and supposedly some compilers have used it to force a variable not to be in a register. ”

    And I seem to remember reading this years ago too - that that is what the use was (variable not in a register).

    Again, nothing major important, so you can consider this nitpicking or trivia or … whatever else.

  • Mike

    Regarding B.2.

    C++11 does have fixed integer types (section 18.4)

  • cocus

    C++11 example of enum struct lacks ‘struct’ or ‘class’ after enum:
    (right after the sentence ‘C++11 defines a new concept, the enum class, which makes enums both strongly typed and strongly scoped.’)
    Should be:

    enum struct Color {

    enum struct Fruit {

Leave a Comment

Put C++ code inside [code][/code] tags to use the syntax highlighter