使用指针到成员进行通用访问

时间:2015-12-31 14:29:37

标签: c++ templates

我有一个班级,其中包含std::map来自玩家的信息(这是一场游戏,是的)。 std::vector必须按递减顺序排序,以便正确呈现记分板(大多数在顶部杀死)。

我已经完成了这个功能非常好的工作。 但它仅限于PlayerScoreBoardInfo::kill结构成员。 请参阅下面的feedvector.push_back(it->second.kill);

如果有任何方式我可以用某种方式替换它,我可以推送任何值而不是::kill成员。嗯,这就是我要问的,怎么做?

我曾尝试使用#define进行黑客攻击,但我已经失败了。

(相信我......因为我想知道这是一个SSEE。)

struct PlayerScoreBoardInfo
{
    std::string name;
    unsigned int kill, death, suicide;
    unsigned int scorestreak;
    PlayerScoreBoardInfo()
    {
        kill = death = suicide = scorestreak = 0;
        name = "";
    }
    PlayerScoreBoardInfo( std::string strname, int nkill, int ndeath, int nsuicide, int nscorestreak )
    {
        name = strname;
        kill = nkill;
        death = ndeath;
        suicide = nsuicide;
        scorestreak = nscorestreak;
    }
};

class GameArenaManager
{
private:
    GameArenaManager() {}
public:
    std::map<u_long, PlayerScoreBoardInfo> m_Infos;
public:
    static GameArenaManager& GetInstance()
    {
        static GameArenaManager InstanceObj;
        return InstanceObj;
    }
};

template <typename T1, typename T2> inline void SortVecFromMap( std::map<T1,T2>& maptodosort, std::vector<T2>& vectosort )
{
    std::vector<T1> feedvector;
    feedvector.reserve( maptodosort.size() );

    for( std::map<T1,T2>::iterator it = maptodosort.begin(); it != maptodosort.end(); it++ )
        feedvector.push_back(it->second.kill);//Here i'm limiting this function to that struct, how can I 'push_back' ANY value here? instead of 'second.kill' only?

    std::sort(feedvector.begin(), feedvector.end(), std::greater<T1>());

    for( std::vector<T1>::iterator itv = feedvector.begin(); itv != feedvector.end(); itv++ ){
        for( std::map<T1,T2>::iterator itm = maptodosort.begin(); itm != maptodosort.end(); itm++ ){
            if( itm->second.kill == (*itv ) )
                vectosort.push_back( itm->second );
        }
    }
}

int _tmain(int argc, _TCHAR* argv[])
{
    GameArenaManager& Manager = GameArenaManager::GetInstance();
    PlayerScoreBoardInfo info[5];
    info[0] = PlayerScoreBoardInfo("Vinicius", 5,4,0,0);
    info[1] = PlayerScoreBoardInfo("Rafael", 9,4,0,0);
    info[2] = PlayerScoreBoardInfo("Marcos", 23,4,0,0);
    info[3] = PlayerScoreBoardInfo("Julius", 1,4,0,0);
    info[4] = PlayerScoreBoardInfo("Ryan", 87,4,0,0);
    for( int i=0; i<5; i++)
        Manager.m_Infos.insert( std::make_pair( i, info[i] ) ); 

    std::vector<PlayerScoreBoardInfo> sortedvec;
    SortVecFromMap( Manager.m_Infos, sortedvec );

    for( std::vector<PlayerScoreBoardInfo>::iterator it = sortedvec.begin(); it != sortedvec.end(); it++ )
    {
        std::cout << "Name: "   <<  (*it).name.c_str()  << " ";
        std::cout << "Kills: "  <<  (*it).kill          << std::endl;
    }

    return 0;
}

(正常工作,输出为:)

Name: Ryan Kills: 87
Name: Marcos Kills: 23
Name: Rafael Kills: 9
Name: Vinicius Kills: 5
Name: Julius Kills: 1

我认为问题标题是错误的,我不知道如何正确地问这个问题,所以随时编辑它。 (请注意我对C ++不是很有经验)

1 个答案:

答案 0 :(得分:4)

对于那些声称“在C ++方面经验不足”的人,你提供了一个非常好的代码;)

如果我理解了这个问题,你需要的是一个指向成员的指针。这是一个例子:

template <...> inline void SortVecFromMap(std::map<T1,T2>& maptodosort, std::vector<T2>& vectosort, unsigned int std::map<T1, T2>::mapped_type::* member )
{
    ...
    feedvector.push_back(it->second.*member);
    ...
}

以下是如何调用它:

SortVerFromMap(my_map, my_vec, &PlayerScoreboardInfo::death);