ID:183887
 
How would you go about making a BYOND-style for loop in C++? I understand how you could do it with an array of only one type of class, but how would you do it with several and only do one type. Example:
mob/verb/foo()
var/list/L=new()
var/mob/M=new()
var/mob/N=new()
var/obj/O=new()
L+=M
L+=N
L+=O
for(var/mob/A in L)
src<<"Mob found!"

This would output "Mob found!" only twice.

Thanks and peace.
LastTroubadour wrote:
I understand how you could do it with an array of only one type of class, but how would you do it with several and only do one type.

The easy answer is that "you don't". =) C++ is a statically typed language. It doesn't handle lists/arrays of different types very well at all.

You can only do it if all of the types you want to put in the array/list have a common base class. Then you can define the array/list as being an array/list of pointers/references to that class. If you then want to loop through the array but only choosing a particular subtype, you need to use either polymorphism or run-time type identification (RTTI) to manually detect the type of each object. Polymorphism is generally considered to be the "cleaner" approach.

I don't recommend just diving into this without some thought first, though. Take a step back and look more closely at the overall design of your code. Do you really need a single list containing objects of different types? Could what you're trying to accomplish be done more cleanly with several separate lists? Or maybe it's cleaner to have a single list and use polymorphism - it depends on the application. For example, for a "contents"-style list I'd probably use one array and polymorphism.

NB. I've been referring to "array" and "list" as separate things throughout - there's a good reason for that. =) In C++, "array" usually means a fixed-size array (in the same sense as plain C). "List" means a dynamic-size array, usually implemented using an STL class (like vector or list).
LastTroubadour wrote:
How would you go about making a BYOND-style for loop in C++? I understand how you could do it with an array of only one type of class, but how would you do it with several and only do one type. Example:
> mob/verb/foo()
> var/list/L=new()
> var/mob/M=new()
> var/mob/N=new()
> var/obj/O=new()
> L+=M
> L+=N
> L+=O
> for(var/mob/A in L)
> src<<"Mob found!"
>

This would output "Mob found!" only twice.

if L is truly one list and its elements are of varying types and are in no specific order, there's no way to iterate over items of a specific type without iterating over all items in the list. simply, if you don't know where in the list all of the mobs are, you have to check every element. so, in c++ you'd just need some way to differentiate between object types. you could use a macro to make the code look clean, but it would still really be iterating over every item and checking its type.

one alternative is to keep separate lists. the list L could be a wrapper for several lists: one list stores objs, another stores mobs (you can have more lists to store more types as needed). items are added to L, but they get placed in separate lists depending on their type. that way you can iterate over all of the objs, mobs, or both.