0

I defined this struct:

typedef struct Systems {
    //stuff...
    vector<double> list;
} System;

vector <System> system(100);

At a certain point I would like to perform an operation on all the 100 entries of system[i].list[0] or system[i].list[1] How it is possible to do this?

on a simple stl vector I would do:

upper_bound(list.begin() list.end(), R)-list.begin();

But using a struct, I found some problems: for example I can't use this:

upper_bound(system.begin().list[1], system.end().list[1], R)-system.begin().list[1];

Could you help me?

A.

altroware
  • 940
  • 3
  • 13
  • 22

2 Answers2

0

One option (which admittedly may not be the best) is to create your own iterator:

class system_iterator :
    public iterator< random_access_iterator_tag, double >
{
public:
    system_iterator() {}
    system_iterator(vector<System>::iterator itr, size_t idx)
        : m_itr(itr), m_idx(idx) {}

    bool operator ==(const system_iterator& rhs) const
        { return m_itr == rhs.m_itr; }
    bool operator !=(const system_iterator& rhs) const
        { return m_itr != rhs.m_itr; }

    double& operator *() const { return (*m_itr).list[m_idx]; }
    system_iterator& operator ++() { ++m_itr; }

    // Define other operations needed for random access iterator
private:
    vector<System>::iterator m_itr;
    size_t m_idx;        
};

Now, you can call:

system_iterator begin( system.begin(), 1 ), end( system.end(), 1 );
System& s = system[ std::upper_bound( begin, end, R ) - begin ];

EDIT : Upgrading the solution after the poster clarified what he/she wanted to do.

MarkB
  • 872
  • 5
  • 13
0

Disclaimer: this is untested.

You have to use the second form of upper_bound, one that takes a value and a comparator.

With C++11 lambdas it's easy:

k = 5;
upper_bound(system.begin(),
    system.end(),
    R,
    [k](double R, System& s) { return R <s.list[k]; });

If you can't use C++11, you will have to write a function that accepts three arguments, (int k, double R, System&)with the same body the lambda above has - use std::tr1::bind to bind the k argument to it. Somerhing like

double func (int k, double R, System& s)
{
  return R < s.list[k];
}

upper_bound(system.begin(),
    system.end(),
    R,
    std::tr1::bind (func, k, _1, _2));

You probably need using namespace std::tr1::placeholders.

Of course in any case you have to make sure your array is sorted by list[k] or at least partitioned w.r.t R.

n. m. could be an AI
  • 112,515
  • 14
  • 128
  • 243