In C++03, stepping through all the values of a sequence requires a lot of code, particularly when using the iterator syntax:
1
|
for
(std::vector<
int
>::iterator itr = myvector.begin(); itr != myvector.end(); ++itr)
|
In C++11, the auto keyword makes this a little better:
1
|
for
(auto itr = myvector.begin(); itr != myvector.end(); ++itr)
|
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”):
1
2
3
4
|
for
(auto x: myvector)
// x is read-only
{
cout << x;
}
|
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
1
2
3
4
|
for
(auto& x: myvector)
// x is modifiable
{
cout << ++x;
}
|
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:
1
|
static_assert(
sizeof
(
int
) >= 4,
"int needs to be 4 bytes to use this code"
);
|
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:
1
|
static_assert(__cplusplus > 199711L,
"Program requires C++11 capable compiler"
);
|
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.