- Learn C++ - https://www.learncpp.com -

B.3 — Range-based for statements and static_assert

Range-based for statements

In C++03, stepping through all the values of a sequence requires a lot of code, particularly when using the iterator syntax:

In C++11, the auto keyword makes this a little better:

But this is such a common pattern that C++11 has introduced an even simpler syntax to allow us to iterate through sequences, called a range-based for statement (or sometimes called “for each”):

You can translate this as “for each value of x in myvector”.

If you want to modify the value of x, you can make x a reference

This syntax works for C-style arrays and anything that supports an iterator via begin() and end() functions. This includes all standard template library container classes (including std::string) and initialization_list (which we’ll cover in the next lesson). You can also make it work for your custom classes by defining iterator-style begin() and end() member functions. If you’re using an older class that doesn’t support begin() and end() member functions, you can write free standing begin(x) and end(x) functions and this syntax will still work.

static_assert

C++03 provides an assert macro that allows testing for assertions at runtime. However, for templated programming, it’s sometimes useful to be able to test assertions at compile type. C++11 provides a new keyword called static_assert that does a compile-time assertion test.

This allows you to do things like ensure the size of variables are what you expect:

Note that because static_assert is checked at compile time, it can not be used to evaluate assumptions that depend on runtime values. Static_asserts is primarily useful for checking the size of things via sizeof() or determining that #defined values are within certain boundaries.

One of the most useful things you can do with static_assert is assert on whether your compiler supports C++11 by checking whether the value of __cplusplus is greater than 199711L:

You may wonder whether it’s redundant to check __cplusplus since compilers that don’t support static_assert will throw a compiler error when they reach the static_assert line. The answer is that it is not redundant, as many compilers (including Visual Studio 2010) have partial support for C++11 and may understand static_assert without having a full C++11 implementation. As of the time of writing, Visual Studio 2010 is in this case: it understands static_assert, but it leaves __cplusplus set to 199711L, because it’s implementation of C++11 is still pretty sparse.

B.4 -- Initializer lists and uniform initialization [1]
Index [2]
B.2 -- Long long, auto, decltype, nullptr, and enum classes [3]