如何将具有相同类型的不同矢量数据成员的类对象传递给可以对这些数据成员中的任何一个进行操作的函数

How to pass a class object with different vector data members of the same type to a function that can operate on any of those data members

本文关键字:数据成员 操作 任何一 函数 对象 同类型      更新时间:2023-10-16

假设我有以下C++代码:

#ifndef _XMaster_
#define _XMaster_
class XMaster
{
public:
    XMaster(string A, string B, string C)
    {
        nM = A;
        oC = B;
        nI = C;
    }
    string nM;
    string oC;
    string nI;
    vector<int> TSNRay;
    vector<int> TSNFor;
};
#endif
void Hershika(vector<XMaster> &Tapren, size_t IS);
int Main()
{
    vector<XMaster> Tapren;
    // Let's just say I have x number of elements in Tapren vector and the vector 
    // data members TSNRay and TSNFor both filled
    size_t IS = 0;
    for(IS; IS < Tapren.size(); ++IS)
    {
        Hershika(Tapren, IS);
    }
    return 0;
}
void Hershika(vector<XMaster> &Tapren, size_t IS)
{
    vector<int>::const_iterator AIT;
    if(!Tapren[IS].TSNRay.empty())
    {
        for (AIT = Tapren[IS].TSNRay.begin() ; 
            AIT != Tapren[IS].TSNRay.end(); ++AIT)
        {
            AnDt(Tapren, *AIT, IS);         
        }
    }   
}

我的问题是,如何使函数Hershika与数据成员TSNRay或TSNFor一起工作,因为它们都是同一类型的?如图所示,它只能访问TSNRay。调用它时,如何指定我需要通过TSNRay或TSNFor?

谢谢!

使用指向成员的指针

typedef vector<int> XMaster::* XMasterVectorPtr;
void Hershika(vector<XMaster> &Tapren, XMasterVectorPtr member, size_t IS);
void Hershika(vector<XMaster> &Tapren, XMasterVectorPtr member, size_t IS)
{
    vector<int>::const_iterator AIT;
    if(!(Tapren[IS].*member).empty())
    {
        for (AIT = (Tapren[IS].*member).begin() ; 
            AIT != (Tapren[IS].*member).end(); ++AIT)
        {
            AnDt(Tapren, *AIT, IS);         
        }
    }   
}

你可以这样称呼它:

Hershika(Tapren, &XMaster::TSNRay, IS);
Hershika(Tapren, &XMaster::TSNFor, IS);

有几种不同的方法可以在不使用指向成员的指针的情况下重写它,例如只接受对要处理的vector<XMaster>vector<int>的引用。如果AnDt()不需要IS参数,这可能允许您删除它。(如果看不到该函数,很难判断。)

使用对目标矢量的引用

第二个选项是简单地要求引用您需要操作的vector<int>

void Hershika(vector<XMaster> &Tapren, vector<int> const &member, size_t IS);
void Hershika(vector<XMaster> &Tapren, vector<int> const &member, size_t IS)
{
    vector<int>::const_iterator AIT;
    if(!member.empty())
    {
        for (AIT = member.begin() ; AIT != member.end(); ++AIT)
        {
            AnDt(Tapren, *AIT, IS);         
        }
    }   
}

这样称呼它:

Hershika(Tapren, Tapren[IS].TSNRay, IS);
Hershika(Tapren, Tapren[IS].TSNFor, IS);

使用Lambda

这是一种仅限C++11的方法,但它可以在两个地方使用,以显著减少代码的大小,同时提高可读性。

template <typename Selector>
void Hershika(vector<XMaster> &Tapren, Selector selector, size_t IS)
{
    auto const & member = selector(Tapren);
    std::for_each(member.begin(), member.end(),
        [&Tapren, IS] (int i) { AnDt(Tapren, i, IS); });
}

这样调用:

Hershika(Tapren, [] (XMaster &x) { return x.TSNRay; }, IS);
Hershika(Tapren, [] (XMaster &x) { return x.TSNFor; }, IS);