简体   繁体   English

用一个函数对两个不同的向量(每个都有“活动”布尔值)进行排序

[英]Sort two different vectors (that each have “active” bool) with one function

I create the base class which has the ACTIVE BOOL 我创建了具有活动布尔值的基类

class BaseTest{
public:
    bool active = false;

    BaseTest(){
    // make most true
        if ( getRand(0, 5) != 2){
            active = true;
        }
    }
};

create two different child classes 创建两个不同的子类

class ChildTest_1: public BaseTest{

    string child1 = "Is child 1";

public:

    ChildTest_1(){

    }
};

class ChildTest_2: public BaseTest{

    string child2 = "Is NOT child 1";

public:

    ChildTest_2(){

    }

};

I want to be able to pass either child (or any vector with "ACTIVE") to this function and it will return the first inactive. 我希望能够将任何一个子代(或任何带有“ ACTIVE”的向量)传递给此函数,它将返回第一个不活动的对象。 I have a program that runs a lot of vectors of many objects and usually have a class that manages each object vector. 我有一个程序,该程序运行许多对象的向量,并且通常具有管理每个对象向量的类。 It is becoming a pain and waste of repeated code to write this loop in every mgmt class. 在每个mgmt类中编写此循环已成为痛苦和浪费的重复代码。 I want one that I can pass any vector that has objects with an active var. 我希望我可以传递任何包含带有活动var对象的向量。

I don't need sorting right now, but that was the closest term to what I need. 我现在不需要排序,但这是最接近我需要的术语。

What I need is a function I can pass a vector to and it will return the first inactive object; 我需要的是一个可以传递矢量的函数,它将返回第一个不活动的对象;

It would be even better if they did not need to share a base class as long as each object in the vector has its own ACTIVE bool, but I can also make a simple base class that all would derive from. 只要它们不需要共享基类,甚至更好,只要向量中的每个对象都有其自己的ACTIVE bool,但我也可以创建一个简单的基类,所有人都可以从中得到基类。

int firstInactive(vector<BaseTest> & test ){

    for ( int cnt = 0 ; cnt < test.size() ; cnt++ ){

        if (!test[cnt].active){

            cout << cnt << " Is inactive " <<endl;

            // add actual sorting here if I need;

            return cnt;
         }

    }

}



int main(int, char const**){



    vector< ChildTest_1 > allTest1;

    vector< ChildTest_2 > allTest2;


    allTest1.resize(10);

    allTest2.resize(10);



    cout << "First inactive in alltest1 is " << firstInactive(allTest1) <<endl;

    cout << "First inactive in alltest2 is " << firstInactive(allTest2) <<endl;

// as expected it says no known matching function call.    

    return 0 ;

}

I've searched and experimented for a few days now. 我已经搜索并尝试了几天。 I've read everything I could on polymorphism and templates, but cannot find an example that helps me. 我已经阅读了有关多态性和模板的所有内容,但是找不到帮助我的示例。

You may use template (No base class required): 您可以使用模板(不需要基类):

template <typename T>
auto firstInactive(const std::vector<T>& v)
// -> typename std::vector<T>::const_iterator // for c++11
{
    return std::find_if(v.begin(), v.end(), [](const T& e) { return !e.active; });
}

and call it: 并称之为:

std::vector<ChildTest_1> allTest1(10);
std::vector<ChildTest_2> allTest2(10);

auto it1 = firstInactive(allTest1);
auto it2 = firstInactive(allTest2);

if (it1 != allTest1.end()) {
    std::cout << "First inactive in alltest1 is "
              << std::distance(allTest1.cbegin(), it1) << std::endl;
}
if (it2 != allTest2.end()) {
    std::cout << "First inactive in alltest2 is "
              << std::distance(allTest2.cbegin(), it2) << std::endl;
}

Demo 演示版

You can use a template: 您可以使用模板:

#include <iostream>
#include <vector>

template <typename T>
T getFirstInactive(const std::vector<T>& v){
    for (const auto& i : v){
        if (!i.active) return i;
    }
    return T();
}

struct Foo{
    bool active;
    int x;
    Foo() : active(true),x(0) {};
};

int main(){
    auto v = std::vector<Foo>(10);
    v[4].active = false;
    v[4].x = 3;
    std::cout << getFirstActive(v).x << std::endl;
}

output: 输出:

3

However, you probably dont want a copy, but a reference to the element. 但是,您可能不想要副本,而只是对元素的引用。 In that case it might be better to make the template return an iterator. 在这种情况下,最好让模板返回一个迭代器。 (Also the template has to return something in case there is no inactive element, which is much nicer with iterators). (如果没有不活动的元素,模板也必须返回某些内容,这对于迭代器来说要好得多)。

I experimented and came up with this solution based on both of your answers: 我进行了试验,并根据您的两个答案提出了此解决方案:

template <typename T>
int getFirstInactive(const std::vector<T> & obj){
    int itr = 0;

    for (const auto& i : obj){

        if (!i.active){
            return itr;
        }

        itr++;

    }

    return itr;

}

this returns the index number of the first inactive object, then all I need is to see if that index number is the same as the size, in which cash I push_back a new object. 这将返回第一个非活动对象的索引号,然后我需要查看的是该索引号是否与大小相同,在其中我将一个push_back现金存入新对象。 problem solved, thanks! 问题解决了,谢谢!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM