I have a situation where I need to find out if a derived object is stored in a vector within another object, and want to functionize this. I can't figure out a way to do exactly what I want, or determine whether it is possible. I have a solution that works which I'm including, but it would be cleaner if there is a direct method to achieve the goal.
This is essentially what I want to do:
class IFruit
{
public:
virtual ~IFruit(){};
};
class Apple : public IFruit {};
class Banana : public IFruit {};
class Orange : public IFruit {};
class FruitBowl
{
public:
bool HasFruit( datatype?? FruitType )
{
for ( auto iter : m_Fruit )
{
if ( typeof( iter ) == typeof( FruitType ) )
{
return ( true );
}
}
return ( false );
}
vector< IFruit* > m_Fruit;
};
int main()
{
FruitBowl Snacks;
Snacks.m_Fruit.push_back( new Banana );
Snacks.m_Fruit.push_back( new Apple );
Snacks.m_Fruit.push_back( new Orange );
if ( Snacks.HasFruit( Orange ) )
{
cout << "There is an orange available";
}
return ( 0 );
}
This is a workaround that achieves the goal, but it has the extra step of providing the callback which I'd love to eradicate:
#include <vector>
#include <iostream>
#include <functional>
using namespace std;
class IFruit
{
public:
virtual ~IFruit(){};
};
class Apple : public IFruit {};
class Banana : public IFruit {};
class Orange : public IFruit {};
class FruitBowl
{
public:
bool HasFruit( function< bool( IFruit* ) > fnCompareFruitType )
{
for ( auto iter : m_Fruit )
{
if ( fnCompareFruitType( iter ) )
{
return ( true );
}
}
return ( false );
}
vector< IFruit* > m_Fruit;
};
int main()
{
FruitBowl Snacks;
Snacks.m_Fruit.push_back( new Banana );
Snacks.m_Fruit.push_back( new Apple );
Snacks.m_Fruit.push_back( new Orange );
if ( Snacks.HasFruit( []( IFruit* TestFruit ){ return ( dynamic_cast< Orange* >( TestFruit ) != nullptr ); } ) )
{
cout << "There is an orange available";
}
return ( 0 );
}
You can't pass a type as a runtime function parameter, but you can use one as a compile time template parameter of a function template:
#include <vector>
#include <iostream>
#include <algorithm>
class IFruit
{
public:
virtual ~IFruit(){};
};
class Apple : public IFruit {};
class Banana : public IFruit {};
class Orange : public IFruit {};
class FruitBowl
{
public:
template <typename T>
bool HasFruit()
{
return std::any_of(m_Fruit.begin(), m_Fruit.end(),
[](IFruit* fruit) {
return dynamic_cast<T*>(fruit) != nullptr;
});
}
std::vector< IFruit* > m_Fruit;
};
int main()
{
FruitBowl Snacks;
Snacks.m_Fruit.push_back( new Banana );
Snacks.m_Fruit.push_back( new Apple );
Snacks.m_Fruit.push_back( new Orange );
if ( Snacks.HasFruit<Orange>() )
{
std::cout << "There is an orange available";
}
}