467,880 Members | 1,256 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 467,880 developers. It's quick & easy.

Custom iterator or custom predicate?

Is there a stylistically preferred way to apply an algorithm to a vector of
vectors?

For example, suppose I have:

typedef vector< vector<int Array2D;
Array2D array2D;

I want to find the top-level element who's 2nd element is the maximum
(think searching on column 2). The obvious algorithm is max_element, but do
I use a custom iterator or a custom predicate?

Should I define a predicate like LessThan2ndElement<Tor an interator
adaptor that converts Array2D::iterator to an interator that, when
dereferenced, returns the 2nd element of the vector<intit points to?
Jun 27 '08 #1
  • viewed: 1833
Share:
5 Replies
Kenneth Porter wrote:
Is there a stylistically preferred way to apply an algorithm to a vector of
vectors?

For example, suppose I have:

typedef vector< vector<int Array2D;
Array2D array2D;

I want to find the top-level element who's 2nd element is the maximum
(think searching on column 2). The obvious algorithm is max_element, but do
I use a custom iterator or a custom predicate?

Should I define a predicate like LessThan2ndElement<Tor an interator
adaptor that converts Array2D::iterator to an interator that, when
dereferenced, returns the 2nd element of the vector<intit points to?
In this case, I'd rather hand write a double loop to iterate

--
Best Regards
Barry
Jun 27 '08 #2
On May 27, 10:07 pm, Kenneth Porter <shiva.blackl...@sewingwitch.com>
wrote:
For example, suppose I have:

typedef vector< vector<int Array2D;
Array2D array2D;

I want to find the top-level element who's 2nd element is the maximum
(think searching on column 2). The obvious algorithm is max_element, but do
I use a custom iterator or a custom predicate?
I agree with Barry, something like (assuming your array size is at
least [1][2]):

int maxv = Array2D[0][1], maxi = 0;
for (int i = 1; i < Array2D.size(); ++ i)
if (Array2D[i][1] maxv) {
maxv = Array2D[i][1];
maxi = i;
}

cout << "max value " << maxv << " at " << maxi << endl;

It's simple, efficient, and clear.

Jason
Jun 27 '08 #3
I went with a custom predicate:

// compares two vectors on the nth element
template <class V, unsigned index>
class VectorElementLess : std::less<V>
{
public:
bool operator()(const V& _Left, const V& _Right) const
{
return std::less<V::value_type>()(_Left[index], _Right[index]);
}
};

typedef std::vector<std::vector<int Array2D;
Array2D samples; // passed in parameter, known to be non-empty

const unsigned sensorIndex = 1;
typedef VectorElementLess<Array2D::value_type, sensorIndexSensorLess;

// find the sample with the maximum sensor reading
std::vector<intmaxSensor = *std::max_element(samples.begin(), samples.end
(), SensorLess());
Jun 27 '08 #4
Kenneth Porter wrote:
I went with a custom predicate:

// compares two vectors on the nth element
template <class V, unsigned index>
class VectorElementLess : std::less<V>
{
public:
bool operator()(const V& _Left, const V& _Right) const
{
return std::less<V::value_type>()(_Left[index], _Right[index]);
Is there any magic using std::less<here?
why not just "return _Left[index] < _Right[index];" ?

name starting with underscore followed by a capital letter is
reserved for implementation usage.

}
};
why inherit from std::less? which introduces a hiding of operator() in
std::less

maybe std::binary_function<V, V, boolis better.
>
typedef std::vector<std::vector<int Array2D;
Array2D samples; // passed in parameter, known to be non-empty

const unsigned sensorIndex = 1;
typedef VectorElementLess<Array2D::value_type, sensorIndexSensorLess;

// find the sample with the maximum sensor reading
std::vector<intmaxSensor = *std::max_element(samples.begin(), samples.end
(), SensorLess());
maybe keep using an iterator as the index found is better

--
Best Regards
Barry
Jun 27 '08 #5
Barry <dh*****@gmail.comwrote in news:g1**********@news.cn99.com:
Is there any magic using std::less<here?
why not just "return _Left[index] < _Right[index];" ?
No, good catch. That would save a template expansion, since at base it's
going to look for operator< to be defined anyway.
name starting with underscore followed by a capital letter is
reserved for implementation usage.
Side effect of copying the compiler's std::less body to base from. I'll fix
that.
why inherit from std::less? which introduces a hiding of operator() in
std::less

maybe std::binary_function<V, V, boolis better.
Just to get the typedefs, but there's no strong reason to use
binary_function versus less, and I figured less might better document
intent. If the standard later extended less, this should allow this class
to inherit the extension.
Jun 27 '08 #6

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

4 posts views Thread by Scott Smedley | last post: by
7 posts views Thread by Prawit Chaivong | last post: by
reply views Thread by nick | last post: by
8 posts views Thread by Mateusz ŇĀoskot | last post: by
6 posts views Thread by samuel.y.l.cheung | last post: by
2 posts views Thread by dkmd_nielsen | last post: by
7 posts views Thread by Max Odendahl | last post: by
reply views Thread by jehugaleahsa | last post: by
reply views Thread by MrMoon | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.