C++11 has provided support for range-based for loops. They allow iterating over the elements of a range without using an index.
std::vector<int> v = {1, 2, 3, 4, 5};
for(auto& e : v)
e *= 2;
However, if you try the following MFC code you get some errors because the compiler is looking for a begin() and end() function that provides access to the first and last element of the range:
void func(CStringArray const & arr)
{
for(auto const & str : arr)
{
// do something with str
}
}
1>error C3312: no callable ‘begin’ function found for type ‘CStringArray’
1>error C3312: no callable ‘end’ function found for type ‘CStringArray’
MFC does not define such functions for its containers.
Enter MFC Collection Utilities
Tom Kirby-Green and I have developed a small open-source library that enables the use of all MFC collection types in range-based for loops. The library is called MFC Collection Utilities and is available on codeplex.
The library consists of a single header, called mfciterators.h, that you include in your MFC projects.
#include "mfciterators.h"
void func(CStringArray const & arr)
{
for(auto const & str : arr)
{
// do something with str
}
}
Compiler and collections support
The library works in Visual Studio 2012 (the first version of the C++ compiler that supports range-based for loops) or a newer version.
The library enables all the MFC collections, both template and non-template, to be used in range-based for loops. This means arrays, lists and maps. For maps you get access to the content through a key-value pair that has two fields: key and value.
Supported template collections
| Arrays | Lists | Maps |
|---|---|---|
| CArray | CList | CMap |
| CTypedPtrArray | CTypedPtrList | CTypedPtrMap |
Supported non-template collections
| Arrays | Lists | Maps |
|---|---|---|
| CObArray | CObList | CMapPtrToWord |
| CByteArray | CPtrList | CMapPtrToPtr |
| CDWordArray | CStringList | CMapStringToOb |
| CPtrArray | CMapStringToPtr | |
| CStringArray | CMapStringToString | |
| CWordArray | CMapWordToOb | |
| CUIntArray | CMapWordToPtr |
Examples
CStringArray arr;
arr.Add("this");
arr.Add("is");
arr.Add("a");
arr.Add("sample");
for(auto & s : arr)
{
s.MakeUpper();
}
class CFoo
{
public:
int value;
CFoo(int const v): value(v) {}
};
CTypedPtrList<CPtrList, CBar*> ptrlist;
ptrlist.AddTail(new CFoo(1));
ptrlist.AddTail(new CFoo(2));
ptrlist.AddTail(new CFoo(3));
for(auto & o : ptrlist)
o->value *= 2;
CMap<int, int, CString, CString> map;
map.SetAt(1, "one");
map.SetAt(2, "two");
map.SetAt(3, "three");
for(auto & kvp : map)
{
kvp.value.MakeUpper();
}
for(auto const & kvp : map)
{
CString temp;
temp.Format("key=%d, value=%s", kvp.key, kvp.value);
}
Download
Version 1.0 can be downloaded from codeplex from here.
For simpler installation you can use the available nuget package.
Let us know if you encounter any issues.

Is
CTypedPtrList ptrlist;
should be
CTypedPtrList ptrlist;
?
Can you elaborate? I don’t see any difference in what you posted. Where is my wrong code?
I mean maybe the CBar* in CTypedPtrList template should be CFoo*?
The angle brackets are eaten 🙂