c ++是否可以将对象类型传递给要进行比较的函数

时间:2016-05-27 04:53:19

标签: c++ polymorphism typeid typeinfo

我有一种情况,我需要找出派生对象是否存储在另一个对象中的向量中,并希望对此进行功能化。我无法找到一种方法来完全按照自己的意愿行事,或者确定是否可行。我有一个解决方案,我可以使用,但如果有一个直接的方法来实现目标,它会更清洁。

这基本上就是我想做的事情:

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 );
}

这是一种实现目标的解决方法,但它提供了额外的步骤来提供我喜欢根除的回调:

#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 );
}

4 个答案:

答案 0 :(得分:7)

您不能将类型作为运行时函数参数传递,但可以使用一个作为函数模板的编译时模板参数:

.icon.ion-spinner-ios {
    display: inline-block;
    background-size: 20px;
    background-image: url("images/ion-spinner-loader.gif");
    background-repeat: no-repeat;
    background-position: center;
    width: 20px;
    height: 20px;
}

答案 1 :(得分:2)

对我而言,解决方案是为所有&#34;水果类型&#34;制作一个枚举。并将其用作参数的数据类型。你可以进行比较

答案 2 :(得分:2)

这样的东西?

#include <iostream>
#include <vector>
using namespace std;

class IFruit {
  public:
    virtual     ~IFruit( void ) { }
} ;

class Apple : public IFruit { };
class Banana : public IFruit { };
class Orange : public IFruit { };

class FruitBowl : public vector<IFruit *> {
  public:
    template <typename T> bool HasFruit( void ) const {
        for (auto i : vector<IFruit *>( *this )) {
            if (typeid(*i) == typeid(T)) return true;
        }
        return false;
    }
} ;

int
main( int, char ** )
{
    FruitBowl b;

    b.push_back( new Apple );
    b.push_back( new Banana );
//    b.push_back( new Orange );

    if (b.HasFruit<Orange>( ))    // thanks M.M.!
        cout << "found one" << endl;
    else
        cout << "no oranges" << endl;

    return 0;
}

也许有一种更性感的方式来打电话? (Orange *)0有点难看。

答案 3 :(得分:1)

也许:

#include<vector>
#include<iostream>
#include<typeinfo>
#include<memory>

using namespace std;

class IFruit
{
public:
    virtual ~IFruit(){};
};
class Apple : public IFruit {};
class Banana : public IFruit {};
class Orange : public IFruit {};

class FruitBowl
{
public:
    //uses tempalte to accept any type
    template<typename FruitType>
    bool HasFruit( FruitType fruit )
    {
        for ( auto iter : m_Fruit )
        {
            if ( typeid(* iter ).hash_code() == typeid( fruit ).hash_code() )
            {
                return ( true );
            }
        }
        return ( false );
    }

    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() ) )
    {
        cout << "There is an orange available";
    }
    else{
        cout<<"No fruit available";   
    }

    return ( 0 );
}

现场演示:http://coliru.stacked-crooked.com/a/37a3e1b4f5567775