What support for STL sets?
Hello,
I need to store ordered sets of various types so I thought STL sets would be just the thing, so I wrote a test programme that began like this:
Code:
#include <QtCore/QCoreApplication>
#include <set>
#include <iterator>
#include <iostream>
using std::cout;
using std::endl;
int main(int argc, char *argv[])
{
set<int> intSet1;
// more follows
Unfortunately the compiler tells me that "set was not declared in this scope".
Is STL not supported, or have I made a mistake?
I'm using QTCreator++ 1.3.0 with MinGW in Windows XP
Re: What support for STL sets?
set is part of the std namespace; you need to refer to it as std::set, or work around it with a 'using' statement as you have for cout and cerr. I'd recommend explicitly qualifying it with std::set, given the commonality of the name.
Re: What support for STL sets?
Thankyou,
My programme works now, and I appreciate the advice concerning the systematic use of std::set.
:)
Re: What support for STL sets?
OK my programme with set<int> was just a warm-up exercise.
What I'd like to do now is create a set whose comparison criterion is based on a Function object, (aka a Functor).
The aim is to compare two dimensional points by comparing their distance from a base point, The base point is something that is going to be moving in the program, so this is implemented as a private field m_basepoint of a class.
The comparison is implemented by overloading the () operator something like this:
Code:
bool operator
()(QPointF p1,
QPointF p2
){return distance
(m_basepoint,p1
) < distance
(m_basepoint,p2
);
}
(where distance is an obvious distance function) and putting this in a class CompareToBase
Unfortunately
it seems that
is not foreseen in STL.
also
Code:
set<QPointF,CompareToBase>
has a problem: how do you set the base_point?
Re: What support for STL sets?
Your operator() should return bool.
Re: What support for STL sets?
Yes, that was a typo. I fixed it, thanks.
Re: What support for STL sets?
Ok, let's suppose my operator returns bool as I should have written.
Somehow going through the STL documentation, I have this feeliing I am going to have to pull out tricks like the use of
bind2nd or something concerning adaptable functors....
Am I looking in the right direction?
All of this brings to mind the Lambda Calculus in disguise.
Re: What support for STL sets?
What is the issue then? You don't know how to initialize the set?
Code:
set<QPointF,CompareToBase> S(a, a+N); //where a is OPointF array of N elements // or for other containers use iterators .begin(), .end()
LE: Documentation for set
Re: What support for STL sets?
Well, the issue is how to set the "memory" or internal state of the comparison, i.e. the value of m_basepoint.
It would be nice if I could set this though set initialisation, but I didnt know i could, I will have another look at the documentation for set.
I suppose you mean the SGI documentation.
Re: What support for STL sets?
m_basepoint has nothing to do with the set, isn't it in the implementation of the class that will be contained in the set? And i recommend to initialize all objects that you create, especially if you want to put them in a std::set (witch must compare objects, so: you can't add uninitialized objects to a set)
And, be careful with set, because it can contain an object only once, if this is a problem then you should look for std::multiset. Choose your containers with care.
The SGI is an implementation of STL, STL itself is only a paper, just like C++ standard, but the container interface should be the same in SGI implementation, GCC, QT, or Microsoft (i think this is done be Dinkumware) or anybody-else who implement the STL...
Re: What support for STL sets?
Yes, m_compare has nothing to do with the set, if we are thinking of mathematical object but it does have an impact on the ordering. You see these sets are not just mathematical sets but they are ordered using a binary tree.
For me the order is very important.
Re: What support for STL sets?
Quote:
For me the order is very important.
That is why you need to have the elements initialized before you can add them to std::set, or std::multiset.
The set can't order your objects if they don't have a value, so the data member must have a value so that set can sort your objects.
The set doesn't know anything about your data, it just calls the CompareToBase functor, witch must be able to tell if one object is smaller (or not) then the other objects that are in set.
So: you need to have the objects created and initialized (read them form keyboard or from file etc) and then you put them in set/multiset (witch will sort them).
Or, if you are not comfortable yet with set/multiset, use an c-style array of your data type and sort it with std::sort like this:
Code:
std::sort(ar, ar+N, CompareToBase); // ar is the array, N is array size, and your CompareToBase functor
or an std::vector, like this:
Code:
std::sort(vec.begin(), vec.end(), CompareToBase); // vec is std::vector<your_data_type>
You need: #include <algorithm> if you use std::sort, anyway you need your data to be initialized, and vector and array don't sort automatically as you add elements.
Re: What support for STL sets?
Thankyou Zlatomir,
Let me try and convince you I know all about adding well initialised elements to my set.
First
set<QPointF> s = new set<QPointF>;
will create an empty set of points.
Then
QPointF *pp = new QpPointF(2.4, 6.88); // sample values
will create a new point pointer
and
s.insert(*pp) will insert the point..
(ok i should probably be using references)
The problem is not about initialisation of the data, it's about passing the function object (functor) to the set s so that s can do its comparison to know where to place the new point.
Re: What support for STL sets?
OK, I found the solution to my problem on another forum.
Simplifying my problem by replacing points by just doubles, but using an "origin" here is the code.
Code:
#include <QtCore/QCoreApplication>
#include <iostream>
#include <math.h>
#include <set>
#include <iterator>
using std::cout;
class origin_comp{
public:
origin_comp(double o):_origine(o){}
bool operator()(double d1, double d2){return fabs(d1 -_origine)< fabs(d2 - _origine);}
private:
double _origine;
};
int main(int argc, char *argv[])
{
std::set<double,origin_comp>::iterator it;
double origin = 4.0;
origin_comp oc(origin );
std::set<double, origin_comp> s(oc);
s.insert(4.5);
s.insert(7.7);
s.insert(0.0);
for(it = s.begin();it != s.end(); it++)
cout<<*it<<" ";
cout << std::endl;
return a.exec();
}
Re: What support for STL sets?
Sorry, my bad, i didn't understand what do you meant by passing functor to set and that data member of your class.
A easier solution would have been to overload operator< for class that is member of set (then you can construct set without functor, and can do comparison of what member you want in operator< )
Re: What support for STL sets?
The key line is line 23 where we have the constructor call s(oc) for the set to which we pass oc, this then makes it possible to
inform the origin comp constructor of the "origin" (state). The existence of this constructor form I was not aware of.
Re: What support for STL sets?
Yes, i know, now i am synchronized ;) sorry for insisted on initializing objects, i didn't understood your problem.
Just a little OOP comment, shouldn't your origine point be a member of your class, i don't like the idea of a "dangling" thing be passed as parameter, because you don't need many origine points, or not know the origine point until run-time, or do you? (i mean the origin stays constant?)
For double, like in example, functor is the way to pass that origine (if is anythig about 0.0), but since you in your project build a class, i think you should encapsulate origine in your class (even if you use functor for comparison).
Re: What support for STL sets?
What is it exactly that you want to represent by this set? To me it seems you can do the same thing with a sorted list or QSet with dedicated qHash() implementation for your objects (which is a direct equivalent of what you are doint with std::set). A set is by definition an unordered structure...