Reputation: 111
I'm a CS student, and the I have a task where I need some help. The task is to create a vectors_predicate_view class that gets a T type parameter, a predictatum as a template parameter and in the constructor it should get 2 std::vector as constructor parameters. While the scope is on the view the vector's items should be sorted depending on the predictatum. Where the predictatum is true, the item should be placed in the constructor's first vector and where it's false everything else should be placed inside the second. If the scope is off the view, everything should be set back to their original state
So my vectors_predicate_view looks like this
#pragma once
#include <vector>
//In this class we add everything to vector1 that gives back true for the predictatum
//everything else goes to vector2
template<typename T, typename Prediktatum>
class vectors_predicate_view
{
private:
Prediktatum predikt;
std::vector<T> originalVector1;
std::vector<T> originalVector2;
public:
vectors_predicate_view(std::vector<T> &vector1, std::vector<T> &vector2)
{
//Putting every element from vector1 into originalVector1
for (auto element : vector1)
originalVector1.push_back(element);
vector1.clear(); //Emptying vector1
//Putting every element from vector2 into originalVector2
for(auto element : vector2)
originalVector2.push_back(element);
vector2.clear(); //Emptying vector2
//We loop through originalVector1
//if the element gives back true for the predictatum, we add it to vector1
//else it goes to vector2
for(auto element : originalVector1)
{
if(predikt(element))
vector1.push_back(element);
else
vector2.push_back(element);
}
//We loop through originalVector2
//if the element gives back true for the predictatum, we add it to vector1
for(auto element : originalVector2)
{
if(predikt(element))
vector1.push_back(element);
}
}
};
and the main WHICH SOULD NOT BE MODIFIED!!! looks like this:
#include <iostream>
#include "vecspred.h"
#include <algorithm>
#include <string>
#include <numeric>
#include <functional>
#include "vecspred.h"
struct is_even: std::unary_function<int, bool>
{
bool operator()( int i ) const
{
return 0 == i % 2;
}
};
struct is_good_language: std::unary_function<std::string, bool>
{
bool operator()( const std::string& s ) const
{
return s == "C++" || s == "C";
}
};
const int max = 1024;
bool check()
{
bool c = false;
std::vector<int> a;
std::vector<int> b;
for( int i = 0; i < max; ++i )
{
if ( i < max / 2 )
{
a.push_back( i );
}
else
{
b.push_back( i );
}
}
std::vector<std::string> x;
x.push_back( "Cobol" );
x.push_back( "Ada" );
std::vector<std::string> y;
y.push_back( "Javascript" );
y.push_back( "C++" );
y.push_back( "ABAP" );
if ( !c )
{
//vectors_predicate_view is in scope now
vectors_predicate_view<int, is_even> va( a, b );
vectors_predicate_view<std::string, is_good_language> vb( x, y );
c = ( 1 == x.size() && 1 == b[ 0 ] && 2 == a[ 1 ] && "Cobol" == y[ 0 ] );
} //after this bracket it's out of scope
//here every vector should be set back to their original state
if ( !c || "Ada" != x[ 1 ] || "ABAP" != y[ 2 ] || max / 2 != b[ 0 ] )
{
return false;
}
return c;
}
int main()
{
std::cout
<< "Your solution is " << (check() ? "" : "not ")
<< "ready for submission.\n";
}
The question is, how can I check in my class if a newly declared vectors_predicate_view object is in scope, without modifying anything in main.cpp?
See for example here:
if ( !c )
{
//vectors_predicate_view is in scope now
vectors_predicate_view<int, is_even> va( a, b );
vectors_predicate_view<std::string, is_good_language> vb( x, y );
c = ( 1 == x.size() && 1 == b[ 0 ] && 2 == a[ 1 ] && "Cobol" == y[ 0 ] );
} //after this bracket it's out of scope
//here every vector should be set back to their original state
if ( !c || "Ada" != x[ 1 ] || "ABAP" != y[ 2 ] || max / 2 != b[ 0 ] )
{
return false;
}
the vectors_predicate_view object is in scope, but after the closing curly bracket it's not. I want to be able to set all the vectors back to their original state in the class, if the object is not in scope anymore.
Any idea how can I do it?
Upvotes: 1
Views: 302
Reputation: 10022
In your constructor, you can make copies of the originals, and keep references to the originals so that you can modify them again. In the destructor, you simply set the vectors back to their originals.
template<typename T, typename Prediktatum>
class vectors_predicate_view {
private:
Prediktatum predikt;
std::vector<T> originalContents1;
std::vector<T> originalContents2;
std::vector<T> &original1; // reference to original vector1
std::vector<T> &original2; // reference to original vector2
public:
vectors_predicate_view( std::vector<T> &vector1, std::vector<T> &vector2 ) : original1( vector1 ), original2( vector2 ) {
//Putting every element from vector1 into originalContents1
for ( auto element : vector1 )
originalContents1.push_back( element );
vector1.clear(); //Emptying vector1
//Putting every element from vector2 into originalContents2
for ( auto element : vector2 )
originalContents2.push_back( element );
vector2.clear(); //Emptying vector2
//We loop through originalContents1
//if the element gives back true for the predictatum, we add it to vector1
//else it goes to vector2
for ( auto element : originalContents1 ) {
if ( predikt( element ) )
vector1.push_back( element );
else
vector2.push_back( element );
}
//We loop through originalContents2
//if the element gives back true for the predictatum, we add it to vector1
for ( auto element : originalContents2 ) {
if ( predikt( element ) )
vector1.push_back( element );
}
}
~vectors_predicate_view() { // destructor automatically called when object goes out of scope
original1 = originalContents1; // reset contents of vector1
original2 = originalContents2; // reset contents of vector2
}
};
There's several improvements that can be made to your code, but I'll leave it as is. The original1
and original2
are references to the two vectors that were passed in; thus, any changes to them affect those vectors. The destructor (~vectors_predicate_view
) is automatically called when the object goes out of scope.
Upvotes: 2