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

时间:2014-10-29 21:50:30

标签: c++ class vector

假设我有以下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?

谢谢!

1 个答案:

答案 0 :(得分:1)

使用指向成员的指针

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>的引用。如果IS不需要,可以允许您删除AnDt()参数。 (如果没有能够看到这个功能,很难分辨。)

使用对目标向量的引用

第二个选项只是要求引用您需要操作的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);

使用lambdas

这是一种仅限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);