使用一个函数对两个不同的向量(每个向量具有" active" bool)进行排序

时间:2016-09-20 17:29:27

标签: c++ templates c++11 vector

我创建了具有ACTIVE BOOL

的基类
Value

创建两个不同的子类

class BaseTest{
public:
    bool active = false;

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

我希望能够将任何一个子(或带有" ACTIVE"的任何向量)传递给此函数,它将返回第一个非活动状态。我有一个程序,它运行许多对象的很多向量,并且通常有一个管理每个对象向量的类。在每个mgmt类中编写此循环正在变得痛苦和浪费重复的代码。我想要一个可以传递任何具有活动变量的对象的矢量。

我现在不需要排序,但这是我所需要的最接近的术语。

我需要的是一个可以传递矢量的函数,它将返回第一个非活动对象;

如果他们不需要长时间共享基类,那就更好了 因为向量中的每个对象都有自己的ACTIVE bool,但我也可以创建一个简单的基类,它都可以从中派生出来。

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(){

    }

};

我现在已经搜索和试验了几天。我已经阅读了关于多态性和模板的所有内容,但找不到帮助我的示例。

3 个答案:

答案 0 :(得分:5)

您可以使用模板(不需要基类):

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

并称之为:

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

答案 1 :(得分:0)

您可以使用模板:

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

输出:

3

但是,您可能不想要副本,而是需要对元素的引用。在这种情况下,最好让模板返回迭代器。 (如果没有非活动元素,模板必须返回一些东西,迭代器更好)。

答案 2 :(得分:0)

我根据你的两个答案进行了实验并提出了这个解决方案:

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;

}

这将返回第一个非活动对象的索引号,然后我需要的是查看该索引号是否与大小相同,其中现金我push_back一个新对象。问题解决了,谢谢!