Reputation: 376
Let's say I have a Light
class, and also SpotLight
, PointLight
and DirectionalLight
which inherits from Light
.
I have a map of Lights like this : std::map<std::string, Light*> LightMap;
I'd like to iterate this map for each type like this:
for ( /* each SpotLight* in LightMap */ ) { ... }
for ( /* each PointLight* in LightMap */) { ... }
etc...
How can I do that ?
Upvotes: 0
Views: 1578
Reputation: 366
I have written some code that will solve your requirement.
class Light {
typedef enum {SpotLight, PointLight, DirectionalLight} LightTypeT;
LightTypeT GetLightType() = 0;
};
class SpotLight : public Light {
LightTypeT GetLightType() { return SpotLight; }
};
class PointLight : public Light {
LightTypeT GetLightType() { return PointLight; }
};
class DirectionalLight : public Light {
LightTypeT GetLightType() { return DirectionalLight; }
};
typedef std::map<std::string, Light*> LightMapT;
LightMapT::iterator be = light_map.begin(),
en = light_map.end();
for (; be != en; be++)
{
Light * m_light = (*be).second;
switch (m_light->GetLightType())
{
case SpotLight :
{
// It is SpotLight
break;
}
case PointLight :
{
// It is PointLight
break;
}
case DirectionalLight :
{
// It is DirectionalLight
break;
}
}
}
Please let me know if it does not solve your problem. We will work on that
Upvotes: 1
Reputation: 100648
You can use dynamic_cast
and a polymorphic base class to determine which type of light you're dealing with:
#include <map>
#include <string>
#include <iostream>
class Light { public: virtual ~Light(){} }; // Light is polymorphic
class SpotLight : public Light {};
class PointLight : public Light {};
class DirectionalLight : public Light {};
int main() {
using namespace std;
map<string, Light*> lightmap;
for (const auto& light : lightmap) {
if (SpotLight* spot = dynamic_cast<SpotLight*>(light.second))
cout << light.first << " is a spot light" << endl;
else if (PointLight* point = dynamic_cast<PointLight*>(light.second))
cout << light.first << " is a point light" << endl;
else if (DirectionalLight* point = dynamic_cast<DirectionalLight*>(light.second))
cout << light.first << " is a directional light" << endl;
else
cout << light.first << " is an unknown light" << endl;
}
}
Upvotes: 1
Reputation: 794
What about something like
for ( /*each Light* lit in LightMap*/)
{
//if lit is instance of Spotlight, do something
}
for ( /*each Light* lit in LightMap*/)
{
//if lit is instance of PointLight, do something
}
For the C++ version of instanceof
, see here
Upvotes: 0
Reputation: 3974
You can't, you'd have to iterate through each item and cast for the class type you want.
for(std::map<std::string, Light*>::iterator iter = m.begin(); iter != m.end(); iter++)
{
if (dynamic_cast<SpotLight*>(*iter))
{
}
}
To avoid using dynamic cast, you could also add functions to your Light class like 'IsSpotLight' which can be overloaded by the SpotLight class to return true, etc.
You could also make separate maps for each type of light so if you need just spot lights, use the SpotLightMap mapping.
Upvotes: 1