views:

88

answers:

2

In C++, I'm looking to implement an operator for selecting items in a list (of type B) based upon B being contained entirely within A.

In the book "the logical design of digital computers" by Montgomery Phister jr (published 1958), p54, it says:

F11 = A + ~B has two interesting and useful associations, neither of them having much to do with computer design. The first is the logical notation of implication... The second is notation of inclusion... This may be expressed by a familiar looking relation, B < A; or by the statement "B is included in A"; or by the boolean equation F11= A + ~B = 1.

My initial implementation was in C. Callbacks were given to the list to use for such operations. An example being a list of ints, and a struct containting two ints, min and max, for selection purposes.

There, selection would be based upon B >= A->min && B <= A->max.

Using C++ and templates, how would you approach this after having implemented a generic list in C using void pointers and callbacks?

Is using < as an over-ridden operator for such purposes... <ugh> evil? </ugh>

(or by using a class B for the selection criteria, implementing the comparison by overloading > ?)

edit: my implementation of the nodes for the list contains a member for flagging item selection or not.

with regards to sets, and uniqueness, the data in the list will likely contain a member specifying position along a time line, given that is one of the main selection criteria, using the term set might be misleading as there is no guaranteed uniqueness regarding position along the time line - that is events can occur simultaneously.

+3  A: 

The way this is done all over the place in the standard library is two have a templated parameter that can take a function/functor and that is used for the comparisons:

template<typename Predicate>
void container::select(Predicate p) {
   if (p(items[0])) {
     // something
   }
}

Some examples from the standard library would remove_if or lower_bound.

(Also be aware that there already is a set class template in the standard library, and algorithms like set_intersection)

sth
+1 for set_intersection. The algorithms of the standard library are too often ignored and yet there is often one that is quite suited to what you're trying to accomplish.
Matthieu M.
perhaps my usage of the term set was wrong in this case, the list will not necessarily contain unique items (where uniqueness is based upon what is being selected by).
James Morris
accepted for mentioning functors - was still thinking in terms of function pointers.
James Morris
A: 

IMO, using '<' would be evil. If it doesn't calculate "less-than", it's probably a misuse.

In this case, I'd model my implementation after STL. I'm not sure this is exactly what you're after, and it's untested but:

Edit: compiled & tested:

#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
#include <functional>
#include <ext/functional>

using namespace std;
using __gnu_cxx::compose2;

int main(int argc, char** argv) {
  vector<int> list_of_b;
  vector<int> included_in_a;

  int min = 2;
  int max = 5;
  remove_copy_if(list_of_b.begin(), list_of_b.end(),
                 back_inserter(included_in_a),
                 not1(compose2(logical_and<bool>(),
                               bind2nd(greater<int>(), min),
                               bind2nd(less<int>(), max))));
  copy(included_in_a.begin(), included_in_a.end(),
       ostream_iterator<int>(cout, "\n"));
  return 0;
}
Stephen
That's not exactly what I'm after no, but then I hadn't mentioned the class I use for nodes in the list has a member for flagging whether an item is selected or not (ie you can select items without removing them).
James Morris