It often happens that I need to iterate over a list of strings in my C++ code.
In languages like Perl, this is easy:
foreach my $x ("abc", "xyz", "123") {.... }
In the past, this is what I've done in C++
const char* strs[] = { "abc", "xyz", "123" };
for (int i=0; i<sizeof(strs)/sizeof(const char*); i++) {
const char *str = strs[i];
...
If I already have an STL container, I can use BOOST_FOREACH
std::vector<std::string> strs;
BOOST_FOREACH(std::string str, strs) {
...
I've tried to create a macro to combine all these concepts but without success.
I'd like to be able to write code like this:
SPECIAL_STRING_FOREACH(const char* str, {"abc", "xyz", "123"}) {
...
}
Surely someone's cooked this up before.
Best Solution
Here is my attempt at it. Sadly it relies on variadic macros which is a C99/C++1x feature. But works in GCC.
Note that you can also iterate with a reference variable, to avoid useless copying. Here is one using
boost.preprocessor
and the(a)(b)...
syntax, compiling down to the same code after pre-processing stage.The trick is to assemble a function type that has as parameter the enumeration variable, and getting the type of that parameter. Then
boost::remove_reference
will remove any reference. First version usedboost::decay
. But it would also convert arrays into pointers, which i found is not what is wanted sometimes. The resulting type is then used as the array element type.For use in templates where the enumerator variable has a dependent type, you will have to use another macro which puts
typename
beforeboost::remove_reference
andboost::function_traits
. Could name itSEQ_FOR_EACH_D
(D == dependent).