Temple of The Roguelike Forums

Development => Programming => Topic started by: Krice on October 12, 2015, 07:52:22 PM

Title: Noob problem with std::map
Post by: Krice on October 12, 2015, 07:52:22 PM
I wanted to try std::map for the first time!

It's int, Message_Text* pair. I'm looking for id from a message data to create map item like this:

map[id]=new Message_Text(text location of id here);

Then checking out with 'find' if the key exists (because if you just use [] to access map it will create a new object if no key found with that id).

The problem is that the text position is wrong so it's doing something to data (even hangs when trying couple of times) or it's not somehow pointing to proper id. I must be missing something simple, right?
Title: Re: Noob problem with std::map
Post by: Cfyz on October 12, 2015, 08:49:45 PM
Yeah. Most likely you've messed something up with the pointers. Hard to tell without the code, but out of the two entities shown -- std::map and 'new Message_Text' -- the latter one is waay more error prone. In modern C++ using raw pointers is a pretty bad practice. You need a damn good reason to use '*' nowadays.
Title: Re: Noob problem with std::map
Post by: Krice on October 12, 2015, 08:57:41 PM
In modern C++ using raw pointers is a pretty bad practice.

I'm not using it in any other way than placing it in the map (I guess?). So it's not even raw.
Title: Re: Noob problem with std::map
Post by: Cfyz on October 12, 2015, 11:56:05 PM
Pointer is either wrapped (e. g. smart pointer) or raw. Raw gets garbage value every chance it gets: at declaration, if not careful with container, when deleting via one of the several copies, etc. and generally is a pain to look after, besides some more architectural drawbacks. After years of practice you start to get around all this intuitively, but in every aspect C-style memory management in C++ just complicate things.

I'm fairly positive it is some (quite possible very simple) mistake in manual memory management. Make that map contain actual values (yep, copies of) instead of pointers to, and no way in hell std container will get you unpredictable results. Well, unless you still messing the heap/stack completely elsewhere =)
Title: Re: Noob problem with std::map
Post by: reaver on October 13, 2015, 07:28:43 AM
1. what's "text location of id"?
2. "no key found with that id" does not make sense. Your id is your key, the value is the Message_Text
Title: Re: Noob problem with std::map
Post by: Krice on October 13, 2015, 08:39:19 AM
Make that map contain actual values (yep, copies of) instead of pointers to, and no way in hell std container will get you unpredictable results

Let's just say the exact same instance created with 'new' works fine with std::vector. But since there are "gaps" in the ids sometimes I thought using map would be a better option. On the contrary I have bad experiences placing actual objects to std containers, because the way it makes the copy. I guess the way std containers are made is really stretching the imagination of C/C++ anyway. So I always put pointers in lists and vectors (not including simple cases like vector of ints) and it's working fine, because the container doesn' t have to copy the objects.

I mean, you CAN put pointers in a map, right? So why isn't this working then?
Title: Re: Noob problem with std::map
Post by: Krice on October 13, 2015, 08:42:48 AM
Pointer is either wrapped (e. g. smart pointer) or raw. Raw gets garbage value every chance it gets: at declaration, if not careful with container, when deleting via one of the several copies, etc. and generally is a pain to look after

I have to disagree. If you follow the ownership paradigm it's really easy to handle "raw" pointers or object instances as I call them. Nothing is lost or no pointer is re-assigned with that paradigm. People who do get in trouble with raw pointers are not doing it right.
Title: Re: Noob problem with std::map
Post by: Krice on October 13, 2015, 09:56:48 AM
Well as always the problem was not in the std::map itself, but in two of my own routines. First when I was creating messages from raw data it was interpreting the data so that there were always at least two versions of the text, even the data had only one. I think this was the reason for hanging, because the second message was garbage. The second bug was in the processing of the text data which made only one letter of message appearing, because I returned false and true in wrong order.

Here's how I handled the insertion:
Code: [Select]
Message_Text *mt=new Message_Text(ptr+t);
texts.insert(std::make_pair<int, Message_Text*>(id, mt));

I guess insert returns something if the id is already in the map, maybe I could check that or it doesn't matter, since the insert just fails if double ids exists.

The map is created in a constructor and items are deleted in the destructor so it's not "raw". And items are searched with find to disallow creation of new empty items.
Title: Re: Noob problem with std::map
Post by: Cfyz on October 13, 2015, 04:17:28 PM
Quote from: Krice
If you follow the ownership paradigm it's really easy to handle "raw" pointers or object instances as I call them. Nothing is lost or no pointer is re-assigned with that paradigm.
Well, that's kind of true. What I want to point out is that std::shared/weak/unique_ptr and value semantics are ownership paradigm personified. Making silly mistakes becomes much harder.
Title: Re: Noob problem with std::map
Post by: Krice on October 14, 2015, 06:44:54 AM
What I want to point out is that std::shared/weak/unique_ptr and value semantics are ownership paradigm personified.

For some reason I don't like C++ smart pointers. I think I have even heard about strange failure of smart pointers in some situations, which sounds quite right, because C++ was never designed for them. I like the direct approach, because then you can be sure it either works or doesn't. Also, often when raw pointers fail it's easy to notice and find the bug. At least with Visual Studio's debug mode.
Title: Re: Noob problem with std::map
Post by: TheCreator on October 14, 2015, 10:57:40 AM
After years of practice you start to get around all this intuitively, but in every aspect C-style memory management in C++ just complicate things.

I guess that everybody should use what they are most accustomed to. After years of practice in using raw pointers you probably won't just switch to smart pointers in a week (even if you can start programming Java in a week). Also, refactoring a big project that has been built on raw pointers is definitely not an option.

I have fixed thousands of memory problems in my life. Most of them were not silly mistakes. They were about not understanding how my own program works (yes, this happens in big projects). Smart pointers can not replace thinking. They're just syntactic sugar that often hides the real problem, which is lack of understanding the code. Once you fully understand the code, you know who is the owner of the memory and managing it becomes easy.
Title: Re: Noob problem with std::map
Post by: Xecutor on October 14, 2015, 03:23:19 PM
Here's how I handled the insertion:
Code: [Select]
Message_Text *mt=new Message_Text(ptr+t);
texts.insert(std::make_pair<int, Message_Text*>(id, mt));
This is potential memory leak. You need to check if an item with this id already exists in the map and only if it doesn't create new Message_Text object.
Or at least delete previous instance if you want to overwrite it.

Code: [Select]
  Message_Text *mt=new Message_Text(ptr+t);
  auto it = texts.find(id);
  if( it != texts.end() ) {
    delete it->second;
    it->second = mt;
  }
  else {
    texts.insert(std::make_pair<int, Message_Text*>(id, mt));
  }

I'll add that in case of pointer wrapper you don't need to care about this :)
Title: Re: Noob problem with std::map
Post by: Krice on October 15, 2015, 09:43:22 AM
This is potential memory leak.

Yes.. so I modified the source somewhat different way, informing if duplicates in message data exist.

Code: [Select]
Message_Text *mt=new Message_Text(ptr+t);

pair<map<int, Message_Text*>::iterator, bool> rv;
rv=texts.insert(std::make_pair<int, Message_Text*>(id, mt));

if (rv.second==false)
printf("Id %d already exists (map size is now: %d).\r\n",
id, (int)texts.size());
Title: Re: Noob problem with std::map
Post by: Cfyz on October 16, 2015, 11:56:43 AM
Quote from: TheCreator
I guess that everybody should use what they are most accustomed to. After years of practice in using raw pointers you probably won't just switch to smart pointers in a week (even if you can start programming Java in a week). Also, refactoring a big project that has been built on raw pointers is definitely not an option.
The latter bit about refactoring a big project is undeniably true. The first two points, however, not so.

Using only what you are accustomed to without thinking is dangerous. Tools evolve and practices change. It's okay to prefer particular alternative, but ignoring years of evolution in computer science is not wise. I probably can guess where you're coming from. AFAIK you primarily use C so this must look like choice between proven, natural approach (manual memory management) and somewhat alien one (automatic memory management). We, however, are talking about C++, where it is as natural and have direct language support. If you are not accustomed to something like that, you are ignoring an integral part of the language. Think about arguing against using structures in C just because you technically can program without them (reductio ad absurdum).

You can switch to smart pointers in a week, unless the project too big or you are pressured for time, etc. but we are talking about fairly small programs here (roguelikes), and most of them are written from scratch (though it may not be the case here). Just as you can switch from homebrew list/map implementations to std::list/std::map in a week. One of the biggest things about smart pointers is they are almost drop-in replacement of a careful version of manual pointer management. Just as std::list is a list does exactly the same as the list implementation you might come up yourself (plus a few other features), smart pointers do exactly the same thing you would end up doing with your pointers yourself. Besides some really specific cases, by using standard library you lose nothing and still gain some.

Quote from: TheCreator
I have fixed thousands of memory problems in my life. Most of them were not silly mistakes. They were about not understanding how my own program works (yes, this happens in big projects). Smart pointers can not replace thinking. They're just syntactic sugar that often hides the real problem, which is lack of understanding the code. Once you fully understand the code, you know who is the owner of the memory and managing it becomes easy.
I find this argument far beside the point. Nothing can replace thinking, be that smart pointers or your hard-earned coding practices. And standard library is not a syntactic sugar. Once again, std::list is not a syntactic sugar over prev/next fields, it is a carefully written and extensively tested double-linked list implementation, written and tested in a way not many can do. In the same manner, std::shared_ptr is very robust implementation of reference-counted pointer container. At best, you'll re-implement the same.

Also note that just because some things might look different, it does not mean they are not one and the same. Both
Code: [Select]
class A {A(); ~A();};and
Code: [Select]
A* alloc_a();
void free_a(A* a);
are essentially the same. Lack of 'class' keyword does not make latter less object-oriented. Similarily, when you are manually managing the memory by keeping track of the pointers, counting references or carefully transferring the ownership, you are doing essentially the same thing as smart pointer will do but without language and compiler support. There are cases where it may be the right approach (e. g. C where there is no language support to begin with) but projects in modern C++ are rarely the ones.
Title: Re: Noob problem with std::map
Post by: TheCreator on October 16, 2015, 01:44:05 PM
AFAIK you primarily use C so this must look like choice between proven, natural approach (manual memory management) and somewhat alien one (automatic memory management). We, however, are talking about C++, where it is as natural and have direct language support.

My previous post might indeed sound like I'm a C programmer, but in fact I've started from Visual Basic and later switched to C++ (like 15 years ago). I've been using stuff like std::string or std::map from the very start, so it's not that I don't value automatic memory management. It's enough to use any raw WinAPI function to see why std::string was such a giant step forward in programming. However, I can't see a single reason why to use smart pointers (apart from one legitimate use of auto_ptr, but that's another story, I guess).

It seems that you are talking about C++11 here. Well, everyone knows it has cool features, but unfortunately some people are stuck in the stone age with their Visual Studio 2005 and can't enjoy that coolness. All the smart pointer support that C++03 has is the infamous auto_ptr, which is not so smart, as you probably know. One day I'll buy a new computer, install new Visual Studio version and port my project to C++11, but before that happens, I would like to learn why smart pointers are as great as they say. There must be something more than just a call to delete at the right moment. Something that would justify the fact that they introduced 3 complicated pointer classes, deprecating a simple
Code: [Select]
type* variable.

Quote
You can switch to smart pointers in a week, unless the project too big or you are pressured for time, etc. but we are talking about fairly small programs here (roguelikes), and most of them are written from scratch (though it may not be the case here).

Well, maybe, I've done such things before. Like switching from char* to std::string in my early C++ days, or switching to Unicode several years ago. However, I would like to see how it will improve the development process, otherwise it would be a lost week for me (and definitely a lot of fun :D).

Quote
And standard library is not a syntactic sugar. Once again, std::list is not a syntactic sugar over prev/next fields, it is a carefully written and extensively tested double-linked list implementation, written and tested in a way not many can do. In the same manner, std::shared_ptr is very robust implementation of reference-counted pointer container. At best, you'll re-implement the same.

OK, I've gone too far saying it's a syntactic sugar. As of shared_ptr's usefulness, I'm not convinced. My biggest problem with reference counting are memory leaks. If I forget to free an object which is tied to a complex hierarchy of objects, all those objects fail to release their dynamically allocated memory and I get a giant leak report. It takes ages to investigate which object has caused a leak. Does shared_ptr address this problem? If it does, I'm already motivated to start using it :).
Title: Re: Noob problem with std::map
Post by: Cfyz on October 16, 2015, 02:57:15 PM
Quote from: TheCreator
However, I can't see a single reason why to use smart pointers (apart from one legitimate use of auto_ptr, but that's another story, I guess).
I'll start with stressing that auto_ptr is one of the few well-known failures of C++. It quickly became obvious it does not fulfill its role and it was promptly deprecated, so I'm afraid there is no legitimate use for it :-) As for the reasons to use smart pointers the main one I believe is a strictly expressed ownership which being checked by the compiler. You can't lose a shared pointer by mistake, you can neither lose nor accidentally copy unique one and you can clearly see from the signature which is which. Also, they integrate seamlessly with value semantics and RAII.

Quote from: TheCreator
It seems that you are talking about C++11 here. Well, everyone knows it has cool features, but unfortunately some people are stuck in the stone age with their Visual Studio 2005 and can't enjoy that coolness.
Well, I do tend to talk about C++11. Which is four years old now and with all major compilers being free it should generally be safe to assume that C++11 is available. It is beside the point of discussion but I am curious why do you still use VisualStudio 2005 when up-to-date versions of this product are available for free.

Still, if we are talking about smart pointers, C++11 is not a must. There is also Technical Report 1 (https://en.wikipedia.org/wiki/C%2B%2B_Technical_Report_1) which was like a preview of C++11 for long years. There are shared_ptr and weak_ptr in std::tr1 namespace. Though I must admit the language support for them is weaker.

Quote from: TheCreator
As of shared_ptr's usefulness, I'm not convinced. My biggest problem with reference counting are memory leaks. If I forget to free an object which is tied to a complex hierarchy of objects, all those objects fail to release their dynamically allocated memory and I get a giant leak report. It takes ages to investigate which object has caused a leak. Does shared_ptr address this problem?
This, I believe, is more an architectural problem which can happen in any language and with any memory management model. As if you can't end up like this with C.

C++ smart pointers, however, do provide some tools to solve this. Specificly, std::weak_ptr which keeps tabs on the object from std::shared_ptr but does not prevent it from being deallocated. It allows to check whether the object is still alive and get a full std::shared_ptr for it. C++ smart pointers represent various degrees of ownership, with std::unique_ptr being the strongest and std::weak_ptr being the weakest. When all your references are expressed like this, circular references naturally break over difference in levels of ownership. Going with your example about some objects (As) being needlessly held alive by some root (B), if B can function without As then its reference to As is weak and they will be deallocated as intended.
Title: Re: Noob problem with std::map
Post by: Krice on October 16, 2015, 04:34:06 PM
but I am curious why do you still use VisualStudio 2005 when up-to-date versions of this product are available for free.

I'm using 2010. The problem with newer versions is that I lost my M$ id and could not recover it. For some reason it was impossible, I don't exactly remember why. What I have heard the newest version is BS anyway.
Title: Re: Noob problem with std::map
Post by: TheCreator on October 19, 2015, 06:11:05 AM
I'll start with stressing that auto_ptr is one of the few well-known failures of C++. It quickly became obvious it does not fulfill its role and it was promptly deprecated, so I'm afraid there is no legitimate use for it :-)

This sounds like a religious belief. Talk to me like an engineer, not like a priest. Sure, auto_ptr is not a general purpose pointer, but it is working. It won't explode if you try to use it :).

Quote
It is beside the point of discussion but I am curious why do you still use VisualStudio 2005 when up-to-date versions of this product are available for free.

They require an up-to-date hardware, I'm afraid, and hardware requires an up-to-date Windows version. I'm not a kind of guy that would happily buy all the new stuff every two years or so. I use the old stuff until it breaks down beyond all repair. Of course, this way I cannot participate in the technical revolution, enjoy smart pointers etc., but guess what - it doesn't worry me that much :).
Title: Re: Noob problem with std::map
Post by: Krice on October 19, 2015, 10:45:32 AM
This is only a related question, but why doesn't list or vector like to use the local object form (non-pointer) when the object has a class instance created with new? You know, now that Tile has a terrain object created with new in Tile's constructor it makes this fail:

Code: [Select]
std::vector<Tile> tilemap;

for (c.y=0; c.y<h; c.y++)
{
for (c.x=0; c.x<w;  c.x++)
{
tilemap.push_back(Tile(bt, c));
}
}

But if you would change Tile to Tile* in the vector it would work. It's just going to be so much fun to change all .'s to ->'s in 1600 lines of Tilemap class.
Title: Re: Noob problem with std::map
Post by: reaver on October 19, 2015, 12:10:48 PM
provide a default constructor perhaps?
Title: Re: Noob problem with std::map
Post by: Krice on October 19, 2015, 12:38:13 PM
More like copy constructor that creates a new instance of that terrain class, because the default copy constructor doesn't make it. This is the problem with std containers that I mentioned earlier, they create a copy of the object. Or then I could change the vector type to Tile* which I think is less painful after all.
Title: Re: Noob problem with std::map
Post by: TheCreator on October 19, 2015, 12:56:47 PM
In fact, to comfortably use a class with standard containers you need both copy constructor and default constructor.
Title: Re: Noob problem with std::map
Post by: Cfyz on October 19, 2015, 01:02:37 PM
Quote
This sounds like a religious belief. Talk to me like an engineer, not like a priest. Sure, auto_ptr is not a general purpose pointer, but it is working. It won't explode if you try to use it :)
Oh yes it will. You are likely to already know, but for the sake of other readers, I'll remind that the main problem with auto_ptr is that its assignment/copy behaviour is literally broken. It actually performs an implicit move instead of a assignment/copy, silently leaving the original empty. Assignment operator not performing assignment, this is a disaster on many levels rendering auto_ptr unusable with standard library (which relies on copying greatly) and prone to counter-intuitive results.

Maybe you are talking about using auto_ptr as a scope-level guard tasked with calling destructor. In this role auto_ptr mainly fails by not providing means to specify a custom deleter. For example, you cannot wrap FILE* or AVFormatContext* in auto_ptr and make it call suitable close function at scope exit (but you can do this with shared_ptr or unique_ptr). This leaves a single scenario where auto_ptr is useful. That would be scope-guarding a temporary polymorphic object dynamically allocated within that scope. This situation is so narrow that I believe (religious, duh!) it is much safer to just outright ban auto_ptr than keep all this quirks in mind. Raw pointers should be better than auto_ptr, if you cannot or refuse to use normal smart pointers.

Quote from: TheCreator
I use the old stuff until it breaks down beyond all repair. Of course, this way I cannot participate in the technical revolution, enjoy smart pointers etc.
There are a few options. If you are not too attached to VisualStudio, there are another IDEs, i. e. Eclipse CDT (quite different but really good after you suffer through a bit). There is also Boost, which is admittedly bloated but you are not compiling by hand and paper, are you? And there is always an option to just copy-paste the relevant source from somewhere. Just saying.

Quote from: Krice
More like copy constructor that creates a new instance of that terrain class, because the default copy constructor doesn't make it. This is the problem with std containers that I mentioned earlier, they create a copy of the object. Or then I could change the vector type to Tile* which I think is less painful after all.
Yes, this is almost certainly a problem with copy constructor not really making a copy. However, this is not a problem with containers but with the class code. By making some container keep references to the objects you will not make you copy constructor behave correctly. Whether you make more problems by using raw pointers or not, you are just masking the problem until the time you'll make a copy, accidentally or not.

I highly encourage you to at least skim through Rules of Three/Five/Zero (https://rmf.io/cxx11/rule-of-zero/).

Note that per rule of zero, smart pointers do help here. It is okay to use default copy constructor if pointer is not raw but reference-counted shared_ptr.
Title: Re: Noob problem with std::map
Post by: Xecutor on October 19, 2015, 02:47:24 PM
Quote
This sounds like a religious belief. Talk to me like an engineer, not like a priest. Sure, auto_ptr is not a general purpose pointer, but it is working. It won't explode if you try to use it :)
Oh yes it will.
I'll add that:
Code: [Select]
  std::auto_ptr<Object> ptr(new Object[n]);
is also a common mistake with auto_ptr that cannot be solved my means of auto_ptr at all.

Title: Re: Noob problem with std::map
Post by: Krice on October 20, 2015, 10:04:19 AM
I need no rules. Anyway, I noticed something interesting when I changed Tile to Tile* in the tile map vector. The size for let's say 100x100 map is of course 10 000 tiles. Now here is the deal: it's slow. Yes. All right then. It's noticeably slow to access the map which can be seen when walking around with (w)alk command. Not only that, it seems to be painfully slow for vector to delete map objects in the destructor. Oh well. I guess it's quite easy to change that vector to raw pointer array. Should be faster. But it's interesting to realize that std::vector is slow, you just don't realize it in most cases. I should actually watch out that, because I also placed tile graphics classes in a vector.
Title: Re: Noob problem with std::map
Post by: Cfyz on October 20, 2015, 11:17:38 AM
Quote from: Krice
I need no rules.
Stubbornly resolving the trouble you keep bringing upon yourself is a noble, albeit foolish endeavor. You are a chaotic neutral character, aren't you?
Title: Re: Noob problem with std::map
Post by: Krice on October 20, 2015, 12:00:35 PM
It's easy to change static size vector to array of pointers, but it was only slightly faster. The worst thing is deleting the maps, I tried to enter 4-5 levels and when quitting the game it takes several seconds to delete the objects in maps. Really. It's this slow? Maybe I need to look at the object class hierarchy and try to create a light weight base class for objects, but still.. or maybe I could wait for 10 years for computer power to catch up!
Title: Re: Noob problem with std::map
Post by: mushroom patch on October 20, 2015, 03:04:44 PM
lol you guys are getting trolled so hard..
Title: Re: Noob problem with std::map
Post by: Krice on October 20, 2015, 09:45:03 PM
Sure.

What I found out is that memory management of lots of small objects is slow I guess. So they say. I just never had that many objects, but now when all terrain tiles are objects the problem is real. Some have solved the problem with some kind of memory manager that allocates a big area of memory and then smaller objects can use that somehow. However first I'm going to try couple of things like removing a std::list item in the base class of objects and see what happens, but I doubt it will change anything.
Title: Re: Noob problem with std::map
Post by: Krice on October 21, 2015, 07:41:16 AM
I think the problem is solved. I tried to run the .exe without IDE and it's blazing fast! What I read Visual Studio is using some kind of special memory management in debug mode which seems to be really slow.

Well, it's still a kind of problem, because I'm constantly running the program and testing stuff, so it can become really annoying.
Title: Re: Noob problem with std::map
Post by: TheCreator on October 22, 2015, 08:41:18 AM
Oh yes it will. You are likely to already know, but for the sake of other readers, I'll remind that the main problem with auto_ptr is that its assignment/copy behaviour is literally broken. It actually performs an implicit move instead of a assignment/copy, silently leaving the original empty. Assignment operator not performing assignment, this is a disaster on many levels rendering auto_ptr unusable with standard library (which relies on copying greatly) and prone to counter-intuitive results.

Maybe you are talking about using auto_ptr as a scope-level guard tasked with calling destructor. In this role auto_ptr mainly fails by not providing means to specify a custom deleter. For example, you cannot wrap FILE* or AVFormatContext* in auto_ptr and make it call suitable close function at scope exit (but you can do this with shared_ptr or unique_ptr). This leaves a single scenario where auto_ptr is useful. That would be scope-guarding a temporary polymorphic object dynamically allocated within that scope. This situation is so narrow that I believe (religious, duh!) it is much safer to just outright ban auto_ptr than keep all this quirks in mind. Raw pointers should be better than auto_ptr, if you cannot or refuse to use normal smart pointers.

Ever heard of a guy named Herb Sutter? Well, he's written an article on auto_ptr:

http://www.gotw.ca/publications/using_auto_ptr_effectively.htm

In short: auto_ptr ain't broken, it's useful, yes, it has some pitfalls, just like anything else in programming.

Quote
There are a few options. If you are not too attached to VisualStudio, there are another IDEs, i. e. Eclipse CDT (quite different but really good after you suffer through a bit). There is also Boost, which is admittedly bloated but you are not compiling by hand and paper, are you? And there is always an option to just copy-paste the relevant source from somewhere. Just saying.

I'd rather use Vim than Eclipse CDT. Eclipse may be a great IDE for Java, but it fails miserably as an IDE for C++. It would be unwise to give up something as good as Visual Studio just to get smart pointers :). As of non-standard libraries, I try to avoid them when I can. This is mainly to avoid situations when my program crashes executing some code I've never seen. It's enough for me that I sometimes need to go through STL source files. Adding another library with its different coding style, different rules, different debugging techniques, different string class etc. is just begging for more trouble.
Title: Re: Noob problem with std::map
Post by: Xecutor on October 22, 2015, 02:36:50 PM
I'd rather use Vim than Eclipse CDT. Eclipse may be a great IDE for Java, but it fails miserably as an IDE for C++.
Wait... what???
Eclipse CDT is probably the best C++ IDE out there from indexing/code completion point of view. CLion is catching up, but it cost too much.
No other C++ IDE have indexer as good as CDT.
But, yes, it requires some configuration. All include paths must be valid, all external macro must be defined.

Title: Re: Noob problem with std::map
Post by: Cfyz on October 22, 2015, 06:26:22 PM
Quote from: TheCreator
Ever heard of a guy named Herb Sutter? Well, he's written an article on auto_ptr
This sounds like a faith in authoritative figure. Talk to me like an engineer, not like an adherent.

That article is old, some points are not even relevant anymore. I've actually went over all three use cases he outlines but this produced a wall of text, a lot of what I've already mentioned earlier, tl;dr auto_ptr either useless or potentially harmful.

On the point of guy named Herb Sutter (as if anyone interested in C++ wouldn't know of him), in the GotW #59 article (http://www.gotw.ca/gotw/059.htm), he demonstrates a kind of tunnel vision, applying the same approach as in the article you referenced to copy-and-swap idiom only to devastate the class interface. Compare and swap that with this much clearer solution (http://stackoverflow.com/questions/3279543/what-is-the-copy-and-swap-idiom).

Quote from: TheCreator
I'd rather use Vim than Eclipse CDT. Eclipse may be a great IDE for Java, but it fails miserably as an IDE for C++.
Somehow you got it backwards, it's Eclipse that is okay IDE for Java (IntelliJ Idea being the best), Eclipse CDT is one of the best IDEs for C++. Visual Studio without plugins is noticeable weaker in code presentation, navigation and management. I cringed in pain on the mention of Vim.
Title: Re: Noob problem with std::map
Post by: Krice on October 22, 2015, 09:58:09 PM
Visual Studio without plugins is noticeable weaker in code presentation, navigation and management.

Is that a fact? I never missed anything from Visual Studio. I'm using a lot of right mouse button over function etc. names and find declaration/definition/references. And 'Find in files'. I hate small details in stuff like that. Code::Blocks has too big menu in right mouse button and first two items are Run to cursor and toggle breakpoint which both are useless, only then comes same find decl.. etc. that VC has.
Title: Re: Noob problem with std::map
Post by: Cfyz on October 23, 2015, 11:51:40 AM
Quote from: Krice
Is that a fact?
Nothing is a fact in discussions like this.

On top of everything VS provides, it also has a lot of really helpful things. For example, on the scrollbar it marks not only positions of static things like errors/warnings and TODOs but also positions of context-dependent like search results and references to whatever the cursor is currently on (with difference in color between access and assignment, even). The whole file at a glance.

Eclipse's 'quick definition peek' is downright awesome. Upon hovering mouse over some symbol, Eclipse show the start of declaration of definition of the symbol along with directly adjacent comments (usually it is a javadoc-style documentation or field summary). If you hover over the popup a while longer it becomes scrollable and shows the entire declaration. You can take a look over the entire type interface or the method implementation with just a mouse-move. For variables it allows to see what that variable was declare-initialized with. For macros the 'peek' will show you a fully expanded version with step-by-step 'macro explore' after you hover over it a bit (a lifesaver when you working with a project with heavy macro usage). Instant code navigation.

Eclipse has templates (wrapping selected code in various predefined blocks or pasting common constructs with a few keypresses) and refactoring (renaming throughout the scope, extracting pieces, implementing stubs).

And lots of smaller things like C++ aware search, quick type hierarchy and includes browsing, 'find references' within the project only, todo markers besides TODO, easier one-button jumping between symbol declaration and definition, etc.

The one thing Visual Studio being undeniable good with is its debugger. I mostly work under Linux so I regularly forget about this stuff, but Eclipse's debugger is GDB and it doesn't perform as well under Windows.
Title: Re: Noob problem with std::map
Post by: TheCreator on October 26, 2015, 08:05:35 AM
This sounds like a faith in authoritative figure. Talk to me like an engineer, not like an adherent.

He must be crazy to use a totally broken pointer class, right? :P

Quote
That article is old, some points are not even relevant anymore. I've actually went over all three use cases he outlines but this produced a wall of text, a lot of what I've already mentioned earlier, tl;dr auto_ptr either useless or potentially harmful.

What was relevant 15 years ago, is still relevant. 15 year could broke my computer or my spine, but it could not break auto_ptr. The fact that the new shiny C++11 is out does not imply that something is wrong with C++03. (By the way, shared_ptr is also potentially harmful, I'd bet you didn't know that.)

Quote
The one thing Visual Studio being undeniable good with is its debugger. I mostly work under Linux so I regularly forget about this stuff, but Eclipse's debugger is GDB and it doesn't perform as well under Windows.

I wouldn't say it's the only thing, but I'd say it's unfortunately the crucial thing. A typical programmer spends 75% of their time debugging, so relying on tools like GDB sounds like masochism and a guaranteed way to a failure. I haven't used Eclipse since about a year, but if I remember correctly, it wasn't even able to display a std::string properly.

Title: Re: Noob problem with std::map
Post by: Krice on October 26, 2015, 08:42:22 AM
A typical programmer spends 75% of their time debugging, so relying on tools like GDB sounds like masochism and a guaranteed way to a failure.

I don't believe that 75% (unless the source code is C?). I'm using the debugger only in rare cases when programming more stuff at a time and then notice something doesn't work. The open/known bugs in Kaduria for example has been less than 10. Besides in my case when I'm using only SDL as external library I can setup the projects so that they can be developed at the same time with Code::Blocks (gcc) and Visual Studio.
Title: Re: Noob problem with std::map
Post by: TheCreator on October 26, 2015, 10:35:25 AM
I don't believe that 75% (unless the source code is C?). I'm using the debugger only in rare cases when programming more stuff at a time and then notice something doesn't work. The open/known bugs in Kaduria for example has been less than 10.

Is the game publicly available? Nope. So you don't know how many bugs you actually have.
Title: Re: Noob problem with std::map
Post by: Cfyz on October 26, 2015, 10:52:43 AM
Quote from: TheCreator
He must be crazy to use a totally broken pointer class, right? :P
Expertise in a field only gives a benefit of a doubt, not a final say.

Quote from: TheCreator
What was relevant 15 years ago, is still relevant. 15 year could broke my computer or my spine, but it could not break auto_ptr.
Not everything. Scope-guarding with auto_ptr is irrelevant. Exception safety with auto_ptr is mostly irrelevant.

Quote from: TheCreator
By the way, shared_ptr is also potentially harmful, I'd bet you didn't know that.
Enlighten me.

Quote from: TheCreator
A typical programmer spends 75% of their time debugging
YMMV? You won't be able to debug realtime (e. g. graphics, complex multithreaded logic, etc.) or situation-dependent (e. g. running on a different hardware) applications in the IDE anyways. Though in the context of the discussion, most roguelikes indeed can be debugged this way.
Title: Re: Noob problem with std::map
Post by: Ancient on October 27, 2015, 04:27:30 AM
relying on tools like GDB sounds like masochism and a guaranteed way to a failure. I haven't used Eclipse since about a year, but if I remember correctly, it wasn't even able to display a std::string properly.
Which is even worse than gdb, because it can pretty print STL structures with an add on. It has steep learning curve but like Vim once basics are mastered I find it preferable to IDE.
Title: Re: Noob problem with std::map
Post by: Krice on October 27, 2015, 07:03:54 AM
Is the game publicly available? Nope. So you don't know how many bugs you actually have.

That's why I wrote "known" bugs. And what releasing has to do with bugs? When I released Teemu no one was able to find bugs (from those 2 people who played the game). In fact I myself found the only known bug the current release version still has (the pedestal in the ancient cave). Although to be honest it must have more bugs, because when I have been programming v1.3 I've noticed how bad the current release version's code actually was (in some areas).
Title: Re: Noob problem with std::map
Post by: Krice on November 24, 2015, 09:47:26 PM
New version of gcc that came with Code::Blocks 15.12 has problems with map and make_pair. This line of  code:

Code: [Select]
rv=texts.insert(std::make_pair<int, Message_Text*>(id, mt));

Stops at error:

Code: [Select]
||=== Build file: Debug in Teemu (compiler: GNU GCC Compiler) ===|
C:\projects\Teemu\messpool.cpp||In constructor 'Message_Pool::Message_Pool(const char*)':|
C:\projects\Teemu\messpool.cpp|39|error: no matching function for call to 'make_pair(int&, Message_Text*&)'|
C:\projects\Teemu\messpool.cpp|39|note: candidate is:|
C:\Program Files (x86)\CodeBlocks\MinGW\lib\gcc\mingw32\4.9.2\include\c++\bits\stl_pair.h|276|note: template<class _T1, class _T2> constexpr std::pair<typename std::__decay_and_strip<_Tp>::__type, typename std::__decay_and_strip<_T2>::__type> std::make_pair(_T1&&, _T2&&)|
C:\Program Files (x86)\CodeBlocks\MinGW\lib\gcc\mingw32\4.9.2\include\c++\bits\stl_pair.h|276|note:   template argument deduction/substitution failed:|
C:\projects\Teemu\messpool.cpp|39|note:   cannot convert 'id' (type 'int') to type 'int&&'|
||=== Build failed: 1 error(s), 0 warning(s) (0 minute(s), 0 second(s)) ===|
Title: Re: Noob problem with std::map
Post by: Xecutor on November 25, 2015, 02:25:36 PM
Actually instead of make_pair you need to use map::value_type:
Code: [Select]
    typedef std::map<int, Message_Text> IdToTextMap;
   IdToTextMap m;
   m.insert(IdToTextMap::value_type(id,msgptr));

or, if you compile your code using C++ standard, you can use:
Code: [Select]
  m.emplace(id,msgptr);
Title: Re: Noob problem with std::map
Post by: Krice on November 25, 2015, 10:56:52 PM
I also read somewhere that you simply need to remove that template part from make_pair and it seems to work.