|
Donno if it could help, but a vector iterator is a RandomAccessIterator, so u can add ur elements in a vector, then apply the sort algorithm
Papa
|
|
|
|
|
That may help, but for now I have simply decided to remove the item from teh set, and re-insert it with a hint of where it should go (because I know where it will end up).
Thanks
Build a man a fire, and he will be warm for a day Light a man on fire, and he will be warm for the rest of his life!
|
|
|
|
|
kilowatt wrote:
Does anyone know if there is a way to force the set container to resort a series of elements?
No there isn't. Either you provide the correct comparator or you don't.
kilowatt wrote:
My only other idea is to remove and reinsert these items into the set. I wuld prefer to do the sort in place if that is possible though.
This is the way you have to do it. A set is by its very (C++) definition sorted. You cant "re-sort" it in the middle of nowhere, using another predicate (for the simple reason that it's predicate is a compile-time type).
I hope the stuff within "()" explained both the reason and the solution.
|
|
|
|
|
Mike Nordell wrote:
A set is by its very (C++) definition sorted. You cant "re-sort" it in the middle of nowhere, using another predicate (for the simple reason that it's predicate is a compile-time type).
I understand that. What I was hoping to do, was force the tree to resort itself based on the same comparitor function. The data in the object has changed and if it were resorted, it would appear in a different place in the tree.
So far I settled on removing the element from the tree, and I know exactly where it would be inserted back into the set, do I have used the insert(iterHint, item) function. A sort routine would have simply been convenient.
Thanks for your help.
Build a man a fire, and he will be warm for a day Light a man on fire, and he will be warm for the rest of his life!
|
|
|
|
|
kilowatt wrote:
What I was hoping to do, was force the tree to resort itself based on the same comparitor function. The data in the object has changed
Then you have violated one of the simple few rules of using an std::set! Now you can expect anything to happen, including getting one of your harddisk reformatted.
Good luck, you'll need it!
|
|
|
|
|
Thanks!
Build a man a fire, and he will be warm for a day Light a man on fire, and he will be warm for the rest of his life!
|
|
|
|
|
BTW, what do you mean by this:
Mike Nordell wrote:
Now you can expect anything to happen, including getting one of your harddisk reformatted.
Build a man a fire, and he will be warm for a day Light a man on fire, and he will be warm for the rest of his life!
|
|
|
|
|
kilowatt wrote:
BTW, what do you mean by this:
Now you can expect anything to happen, including getting one of your harddisk reformatted.
Changing the contents of a set in such a way that the entries all of a sudden starts to compare in another order than they were inserted I believe invokes undefined behaviour.
Undefined behaviour means that about anything could happen, including (but not limited to):
- Starting and stopping your microwave oven three times in the middle of the night.
- Making Windows stop BSOD on you.
- Put the cat in the dishwasher.
- Reformat your harddisk.
- Send all your pr0n to billg@microsoft.com using your 28k8 modem.
- Make your neighbour order a years supply of nylon stockings to Brad Pitt... in your name.
- Put your pants on fire.
- Making the shower water really really cold, for no apparent reason.
- Send secret messages to your brain while you are asleep.
- Making you look really really strange by forcing you to start singing "Kumba Ya" every time you're in the middle of a crowd.
- Making your eyes extremely sensitive to ligt. You know, like when you have been hacking all night long and all of a sudden is forced to go outside and see that very very bright light. That sensitive!
- Sending embarrasing pictures of you and your cat to your ISP, forcing them to shut down your connection while they investigate.
- Time-warp you to a different dimension where everyones fingers are really short and worn down curtesy of COBOL Injuries Inc.
- Make your harddisk make strange noises. Like that time you heard that strange noise from the front wheel of your bicycle, like a ball bearing is about to break, just before it completely broke down, catapulting you into the best looking girl in the class and made everyone laugh. That kind of noise.
- Install Clippy, and no matter how you try you can't stop it from popping up, telling you "It looks like you are writing a letter to grandma'. Do you want me to help you? [OK]" every three minutes, even that YOU see no resemblance between your current C++ code and a letter to grandma'.
- Make you buy a little black secret book, and every day you take frequent notes of what time it is in case you should loose your watch.
- Inject code into your editor, making it cheerfully replace every second instance of the word "bool" with "ball". When you try to change it back a cheerful Clippy will pop up telling you "It looks like you are writing a letter to grandma'"...
Note that these are only examples!
Windows completed installation of WfW 3.11. Please wait... Rebooting... Nope, didn't work, you'll have to do it yourself.
|
|
|
|
|
Have any of these things ever happened to you? Is that how you know of these examples?
Build a man a fire, and he will be warm for a day Light a man on fire, and he will be warm for the rest of his life!
|
|
|
|
|
Hehe.
No, I've never experienced any of the above. The worst I've experienced invoking undefined behaviour was one piece of code that seemed to work. The best was when it SEGV'd on me.
|
|
|
|
|
My guess is that none of the STL sorting algorithms will work, and even if they do sometimes, it is not safe to rely on them. Non-const iterators on sets are a controversial matter, and replacing the contents of a set thru an iterator can lead to non-conforming code in future revisions of the standard (The essential problem is that std::set is suppose to hold the invariant that all elements are sorted, which one can obviously subvert by replacing an element pointed to by a non-const iterator.)
That said, your best option would be probably something like this:
void resort(mymap& m)
{
mymap mm=m;
m.swap(mm);
}
Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo
|
|
|
|
|
Thats a good idean, I hadn't thought of that. I may test it out to see if swap will force the re-sort. However I do not think that would be the best solution in my situation because I will have about 10000 items in the tree, and will only need to resort about 8-20 items in the set.
I think that removing the items and re-inserting them with a hint of where they should go (I know the exact place where it will be reinserted) will be a better solution for me here. I was just looking for a slick way to do it with one generic function
Thanks for the idea.
Build a man a fire, and he will be warm for a day Light a man on fire, and he will be warm for the rest of his life!
|
|
|
|
|
I was wondering if any of you know how to compare two classes identify whether or not they are of the same type without know what type they are. In MFC you'd write somthing like this:
fruit1->IsKindOf(fruit2->GetRuntimeClass()); Problem is though that I am deliberatly trying to avoid using MFC, so is there some way using the C++ language, or is there some "home made" runtime class library available?
Thanks for your time...
With time we live, with money we spend!
Joel Holdsworth
|
|
|
|
|
In standard C++, you'd write it like this:
typeid(fruit1)==typeid(*fruit2);
PS: Ummm. The latter just checks whether fruit1 and fruit2 are of he same type. Determining if fruit1 is derived from the the type fruit2 seems a little harder. I'll think it over to try to find a solution.
Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo
|
|
|
|
|
OK. To determine wheter fruit1 derives from the type of fruit2 , you have to know at compile time the exatc type of fruit2 . Suppose both objects are Fruit s and moreover fruit2 is an Apple . Then you'd write something like this:
dynamic_cast<Apple*>(fruit1)!=0 In C++, you can't get closer to the semantics of IsKindOf , but usually this is close enough, since you can do little with the type of an object ar run-time if you didn't know it before at compile-time --I hope I'm making myself clear enough.
Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo
|
|
|
|
|
The only problem is that you need to enable RTTI and that increases the size of compiled code a lot. then you run into all kind of problems like linking with libraries without RTTI etc.
|
|
|
|
|
The only problem is that you need to enable RTTI and that increases the size of compiled code a lot.
Does it? I'd bet MFC's run-type schema adds a lot more code bloat to the app, and it is less efficient than RTTI, which after all is natively handled by the compiler. As for linking problems, you won't find any more problems as with any other RT schema external developers would have to implement anyway to be compatible with you.
Having RTTI switched off by default by VC++ is, to put it simply, non-standard, and a very bad decision IMHO.
Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo
|
|
|
|
|
Joaquín M López Muñoz wrote:
Does it? I'd bet MFC's run-type schema adds a lot more code bloat to the app, and it is less efficient than RTTI,
No this is not true. RTTI simply adds too much extra code. I will write an article on it soon.
Joaquín M López Muñoz wrote:
Having RTTI switched off by default by VC++ is, to put it simply, non-standard, and a very bad decision IMHO.
Even strourstrup recommends in his book not use RTTI.
|
|
|
|
|
No this is not true. RTTI simply adds too much extra code. I will write an article on it soon.
RTTI adds some bytes of information for each polymorphic class. I doubt this can generate much code bloat. Nevertheless, it'll be interesting to know what you come up with in your forthcoming article.
Even strourstrup recommends in his book not use RTTI.
Yep, but one thing is advising against RTTI and other recommending that RTTI be not included in the object code by default (which is, to say it once more, non-standard), or recommending that one writes RTTI replacements.
Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo
|
|
|
|
|
Joel Holdsworth wrote:
fruit1->IsKindOf(fruit2->GetRuntimeClass());
Does this really tell you if fruit2 is of the same type as fruit1? Wouldn't this only tell you if fruit2 was of the same type _or an inherited type_ as fruit1?
Perhaps if you tell us what you want to accomplish there is a better way to do it? RTTI is almost always not the way you want to travel. Also be aware that MFC is often the blueprint of how not to do something.
|
|
|
|
|
Mike Nordell wrote:
RTTI is almost always not the way you want to travel.
Good point. I agree.
|
|
|
|
|
You can use RTTI but I don't recommend it. It adds lot of unecessary code. The easiest way for you would be to imitate what MFC does. i did have a set of classes to imitate this feature I will post it here if I find them.
|
|
|
|
|
I could partially agree with your advise of not using RTTI if avoidable, but imitating what MFC does (i.e. replacing RTTI with your own homemade schema) is usually much worse than relying in RTTI.
Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo
|
|
|
|
|
Joaquín M López Muñoz wrote:
but imitating what MFC does (i.e. replacing RTTI with your own homemade schema) is usually much worse than relying in RTTI.
Indeed. Fortunately there often are (way better) alternatives to do stuff than the MFC way.
|
|
|
|
|
Here is a simple implementation of RuntimeClass mechanism to give you an idea.
#include "assert.h"
class RuntimeObject;
class RuntimeClass
{
private:
RuntimeClass* m_pBaseClass;
private:
RuntimeClass()
: m_pBaseClass(NULL)
{
}
protected:
RuntimeClass(RuntimeClass* pBaseClass)
: m_pBaseClass(pBaseClass)
{
}
public:
virtual RuntimeClass* GetBaseClass()
{
return m_pBaseClass;
}
virtual RuntimeObject* CreateInstance();
friend class RuntimeObject;
};
class RuntimeObject
{
public:
RuntimeObject()
{
}
virtual RuntimeClass* GetRuntimeClass()
{
return &_runtimeClass;
}
bool IsKindOf(RuntimeClass* pClass);
static RuntimeClass _runtimeClass;
};
template<class T, class Base>
class RuntimeClassImpl : public RuntimeClass
{
public:
RuntimeClassImpl(RuntimeClass* pBaseClass)
: RuntimeClass(pBaseClass)
{
}
RuntimeObject* CreateInstance()
{
return new T();
}
};
template<class T, class Base>
class RuntimeObjectImpl : public Base
{
public:
RuntimeClass* GetRuntimeClass()
{
return &_runtimeClass;
}
static RuntimeClassImpl<T, Base> _runtimeClass;
};
template<class T, class Base>
RuntimeClassImpl<T, Base> RuntimeObjectImpl<T, Base>::_runtimeClass(&Base::_runtimeClass);
bool RuntimeObject::IsKindOf(RuntimeClass* pClass)
{
RuntimeClass* pThisClass = this->GetRuntimeClass();
while(pThisClass)
{
if (pThisClass == pClass)
return true;
pThisClass = pThisClass->GetBaseClass();
}
return false;
}
RuntimeClass RuntimeObject::_runtimeClass;
RuntimeObject* RuntimeClass::CreateInstance()
{
return new RuntimeObject();
}
//A derives from RuntimeObject
class A : public RuntimeObjectImpl<A, RuntimeObject>
{
};
//B derives from A
class B : public RuntimeObjectImpl<B, A>
{
};
//C derives from A
class C : public RuntimeObjectImpl<C, A>
{
};
int _tmain(int argc, _TCHAR* argv[])
{
C c;
A a;
B b;
assert(c.IsKindOf(a.GetRuntimeClass()));
assert(b.IsKindOf(a.GetRuntimeClass()));
assert(!c.IsKindOf(b.GetRuntimeClass()));
return 0;
}
|
|
|
|