Humam Helfawi
Humam Helfawi

Reputation: 20284

Relate two variables to change together

Is it possible to relate two variable to be changed together?

Example:

class foo{
public:
     std::vector<int> v1;
     std::vector<float> v2;

     //Imaginary Code here:
     void on_v2_change(){
          std::transform(begin(v2),end(v2),begin(v1),[](auto& item){ return std::round(item);});
     }
}

int main(){
    foo bar;
    bar.v2.push_back(5.7);
    //v2={5.4}
    //v1={5}
}

Is there a straightforward way to implement the previous? something like Java or C# events.

Upvotes: 1

Views: 162

Answers (4)

Jarod42
Jarod42

Reputation: 217810

You may write a wrapper with events, something like:

template<typename V>
class vector_observer
{
    virtual ~vector_observer() = default;
    virtual void on_push_back(typename V::const_reference value) = 0;
    virtual void on_clear() = 0;
    // ...
};

template<typename T>
class observed_vector
{
private:
    std::vector<T> vec;
    vector_observer& obs;
public:
    explicit observed_vector(vector_observer& obs) : obs(obs) {}

    void push_back(const T& value) { vec.push_back(value); obs.on_push_back(value); }
    void clear() { vec.clear(); obs.on_clear(); }
    // ...
};

and

class to_int_vector_observer : public vector_observer<std::vector<float>>
{
public:
    explicit to_int_vector_observer(std::vector<int>&vec) : vec(vec) {}

    void on_push_back(float value) override{ vec.push_back(round(value)); }
    void on_clear() override { vec.clear(); }

private:
    std::vector<int>& vec;
}

Upvotes: 1

noname
noname

Reputation: 43

Although diversion of operator () is not a solution very compliant C++ ...

#include "stdafx.h"
#include <vector>

class vectorFloatAndInt : public std::vector<float>
{
public:
    inline int operator () (unsigned int paramPos)
    {
         return std::round((*this)[paramPos]);
    }
};

int main()
{
   vectorFloatAndInt bar;
   bar.push_back(5.4);

   float vf = bar[0];    // == 5.4
   int vi = bar(0);      // == 5
   return 0;
}

Upvotes: 0

Prashant Singh
Prashant Singh

Reputation: 51

Using template class and function, make generic and convert input at the time of passing as argument.

#include <iostream>
#include <vector>

template <class T1, class T2>
class Stack {
  private:
    std::vector<T1> v1;
    std::vector<T2> v2;

  public:
  template<typename T3, typename T4>
  void push (T3 v,  T4 flag) {
    if(flag)
        v1.push_back(v);
    else
        v2.push_back(v);
  }
};

int main() {
  Stack<int,float> stack;
  stack.push(7,0);
  stack.push((int)7.5,1);
}

Or further it can be modified as per requirement like float -> int transformation can be done in push method as per use and design.

Upvotes: 0

thefunkyjunky
thefunkyjunky

Reputation: 522

I don't know if you can use exactly this syntax, but you can use the following:

class foo {
    std::vector<int> v1;
    std::vector<float> v2;

    public:
    void push_back(float val) {
        v1.push_back(std::round(val));
        v2.push_back(val);
    }
    // ....

You can also add similar functions for other functionality(like erase()). As far as I know, there is no other way to change two vectors at once.

Upvotes: 2

Related Questions