Martin Serdült
Martin Serdült

Reputation: 111

Check if object is in scope

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

Answers (1)

ChrisMM
ChrisMM

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

Related Questions