Iterate over a BObjectList?

I’m having some trouble getting started with C++.
For example, how can one iterate (with EachElement) over a BObjectList? Forgive me if I missed the appropriate documentation with an appropriate example. My sample code looks like this:

#include <iostream>
#include <ObjectList.h>
#include <String.h>
class ListDemo
{
public:
	ListDemo(void);
	void DoDemo(void);
	void PrintIt(BString* str);
};

#include "ListDemo.h"
ListDemo::ListDemo(void)
{
}

void
ListDemo::PrintIt(BString* str)
{
	std::cout << str->String() << std::endl;
}

void
ListDemo::DoDemo(void)
{
   // Create a BList to store strings
    BObjectList<BString> aList;

    // Add some strings to the list
    aList.AddItem(new BString("alpha"));
    aList.AddItem(new BString("beta"));
    aList.AddItem(new BString("gamma"));

   //...

    //aList.EachElement(PrintIt); //HOW???
  
}

Thank you for your attention!

Your PrintIt function has to be either a “free” C function, or a static method. You are trying to pass a class method, which takes an extra hidden argument (the “this” pointer) and so has an incompatible type

1 Like

Hi @retronym67,
The signature of PrintIt is wrong! It must match the type parameter provided to BObjectList and needs an addiitonal void* param.
The correct definition would be:

BString* PrintIt(BString* str, void* param)
{
	std::cout << str->String() << std::endl;
	return str;
}

And EachElement should be invoked as:

aList.EachElement(PrintIt, nullptr);

Replace nullptr with whatever value you need and adjust PrintIt accordingly.
Also PrintIt must return 0 if you want to continue the iteration, str to bail out.

If you are using C++11 or higher you can also use a lambda that does not capture:

auto lambda = [](BString* str, void* param)
{
	std::cout << str->String() << std::endl;
	return str;
};

aList.EachElement(lambda, nullptr);

Or more concisely:

aList.EachElement([](BString* str, void* param)
					{
						std::cout << str->String() << std::endl;
						return str;
					}, nullptr);

Lambdas decay to free functions or static methods as long as they do not capture anything.

1 Like

Thank you! That’s how it works for me:

#include <iostream>
#include <ObjectList.h>
#include <String.h>

BString* PrintIt(BString* str, void* someContextParam)
{
	std::cout << str->String() << std::endl;
	return 0; //continue with the iteration
}

int main() {
	BObjectList<BString> list;
	
	list.AddItem(new BString("alpha"));
	list.AddItem(new BString("beta"));
	list.AddItem(new BString("gamma"));
	
	list.EachElement(PrintIt, NULL);
	
	return 0;
}