Search

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
Index
B.2 -- Long long, auto, decltype, nullptr, and enum classes

8 comments to B.3 — Range-based for statements and static_assert

  • silviu

    The answer is that it is not redundant, as many compilers (including Visual Studio 2010) have partial support for C++11

    this is also true in Visual Studio 2013…

  • Harshul

    One thing the range based loops are majorly created to iterate over data structures. But different data structures could have different implementations so how do they iterate over the data elements of a data structure??

    • Alex

      Range based for loops use iterators behind the scenes. So as long as the class supports iterators via standard iterator functions begin() and end(), then it should work with range-based for.

  • Harshul

    So the iterators have all the details of traversal in background which is being used by data structures. Can I use range based loops for simple arrays which don’t have any iterators defined( int a[10] ). What is the way to create an iterator with which I can use range based loop??

    • Alex

      No, range-based for loops won’t work with simple arrays because simple arrays don’t have iterators.

      You can create iterators for your own classes, but that’s really an entire lesson on it’s own (and one I have on my to-do list to write).

      • Harshul

        Hope so that you will upload new tutorial on user defined iterators soon, I will be waiting for that.

        Why don’t to add advanced stuff to you tutorials like multithreading it will be great for learners too…

  • Harshul

    In your example you have also used auto keyword so how did loop detect the correct iterator for the data structure??

    • Alex

      You’re mixing up concepts. Auto tells the compiler to infer the type from the object being evaluated, so we don’t have specify it explicitly. The compiler can’t infer anything it doesn’t already know.

      That said, in our range-based for loop, we use auto to infer the type of an individual element. However, the iterators that the range-based for loop uses work at the container class level (e.g. they are part of the vector, not the vector elements).

Leave a Comment

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