Reputation: 1
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. 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. I want one that I can pass any vector that has objects with an active 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.
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.
Upvotes: 0
Views: 87
Reputation: 1
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. problem solved, thanks!
Upvotes: 0
Reputation: 217810
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;
}
Upvotes: 5
Reputation: 122830
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).
Upvotes: 0