Skip to main content

BOOST_FOREACH

BOOST_FOREACH is a preprocessor macro that provides range-based iteration on compilers that lack the C++11 range-for loop. It was an essential tool in the C++03 era; today it is obsolete — the language-level for (auto& x : container) does the same thing, more safely and more readably.

The problem it solved

Before C++11, iterating a container required writing for (std::vector<int>::iterator it = v.begin(); it != v.end(); ++it) — verbose, error-prone, and hard to read. BOOST_FOREACH compressed that into a single macro call that looked almost like the range-for syntax that would come later.

Basic usage

foreach_demo.cpp
#include <boost/foreach.hpp>
#include <vector>
#include <iostream>

int main() {
std::vector<int> v{1, 2, 3, 4, 5};

BOOST_FOREACH(int x, v) {
std::cout << x << " ";
}
std::cout << "\n";

// Modifying elements: take by reference
BOOST_FOREACH(int& x, v) {
x *= 2;
}
// v is now {2, 4, 6, 8, 10}
}

What it expands to

BOOST_FOREACH(var, range) roughly expands to a for loop using boost::begin / boost::end. It handles arrays, standard containers, iterator pairs, and null-terminated strings.

Supported range types

Range typeExampleWorks
Standard containerstd::vector<int>yes
Raw arrayint arr[5]yes
C stringconst char*yes
std::pair<Iter, Iter>iterator pairyes
Custom type with begin/enduser-definedyes
Rvalue temporaryget_vector()yes (copies the range)
Rvalue ranges are copied

When you pass a temporary (rvalue) to BOOST_FOREACH, it copies the entire container to prevent dangling. This is safe but potentially expensive for large containers.

BOOST_REVERSE_FOREACH

Iterates in reverse order — equivalent to using rbegin / rend:

reverse_foreach.cpp
#include <boost/foreach.hpp>
#include <vector>
#include <iostream>

int main() {
std::vector<int> v{1, 2, 3, 4, 5};

BOOST_REVERSE_FOREACH(int x, v) {
std::cout << x << " "; // 5 4 3 2 1
}
std::cout << "\n";
}

Why range-for replaces it entirely

The C++11 range-for loop does everything BOOST_FOREACH does, without the macro overhead:

comparison.cpp
#include <vector>
#include <iostream>

int main() {
std::vector<int> v{1, 2, 3, 4, 5};

// C++03 with BOOST_FOREACH:
// BOOST_FOREACH(int x, v) { std::cout << x; }

// C++11 range-for — same thing, no macro:
for (int x : v) {
std::cout << x << " ";
}
std::cout << "\n";

// C++11 with references:
for (int& x : v) {
x *= 2;
}
}
BOOST_FOREACHRange-for (C++11)
Syntaxmacrolanguage feature
Rvalue handlingcopies (safe but slow)well-defined since C++20
Structured bindingsnoyes (C++17)
Debugger supportlimited (macro expansion)full
Init statementnoyes (C++20)
Breakpointshit macro internalsclean single-step
Do not use BOOST_FOREACH in new code

There is no reason to use this macro in any project compiled with C++11 or later. It exists only for backwards compatibility with C++03 codebases. If you encounter it in legacy code, replacing it with a range-for loop is a safe, mechanical refactor.

Migrating away

Replacing BOOST_FOREACH is straightforward:

migration.cpp
// Before:
// BOOST_FOREACH(const std::string& s, names) { process(s); }

// After:
// for (const std::string& s : names) { process(s); }

// Before (reverse):
// BOOST_REVERSE_FOREACH(int x, v) { process(x); }

// After:
// for (int x : v | boost::adaptors::reversed) { process(x); }
// or with std::ranges::views::reverse in C++20

See also