--- Log opened Sat Jan 16 00:00:11 2010 |
00:04 | | Derakon[gonk] [Derakon@Nightstar-1ffd02e6.ucsf.edu] has quit [[NS] Quit: Leaving] |
00:27 | | You're now known as TheWatcher[T-2] |
00:30 | | You're now known as TheWatcher[zZzZ] |
00:37 | < Rhamphoryncus> | Isn't it something like "$foo" to get separate arguments? (yes, the syntax is a WTF too) |
00:39 | <@McMartin> | Rhamphoryncus: That looks more like Perl. |
00:40 | | Derakon [Derakon@Nightstar-5abd3ac9.ca.comcast.net] has joined #code |
00:40 | | mode/#code [+o Derakon] by Reiver |
00:54 | | Vornicus-Latens is now known as Vornicus |
01:40 | | Vornicus [vorn@ServerAdministrator.Nightstar.Net] has quit [[NS] Quit: Leaving] |
01:41 | | Phas [vorn@ServerAdministrator.Nightstar.Net] has joined #code |
01:44 | | Phas is now known as Vornicus |
02:11 | | Attilla [Attilla@FBC920.DDABA2.60661C.0EE0F8] has quit [Connection reset by peer] |
02:19 | | Derakon is now known as Derakon[AFK] |
03:43 | | gnolam [lenin@Nightstar-38637aa0.priv.bahnhof.se] has quit [[NS] Quit: Z?] |
04:45 | | Vornicus is now known as Phas |
05:21 | | Alek [omegaboot@Nightstar-3f3964f1.emhril.sbcglobal.net] has quit [Ping timeout: 121 seconds] |
06:24 | | celticminstrel [celticminstre@Nightstar-f8b608eb.cable.rogers.com] has quit [[NS] Quit: *hums* Can't stay now!] |
06:50 | | Derakon[AFK] is now known as Derakon |
07:23 | | Derakon is now known as Derakon[AFK] |
07:24 | | Phas is now known as Vornicus |
07:38 | | Vornicus is now known as Vornicus-Latens |
07:44 | | Alek [omegaboot@Nightstar-3f3964f1.emhril.sbcglobal.net] has joined #code |
08:47 | | Tarinaky [Tarinaky@Nightstar-724e7fcf.adsl.virginmedia.net] has quit [Ping timeout: 121 seconds] |
09:01 | | Tarinaky [Tarinaky@Nightstar-06637221.adsl.virginmedia.net] has joined #code |
09:05 | | Rhamphoryncus [rhamph@Nightstar-a62bd960.abhsia.telus.net] has quit [Client exited] |
09:26 | | Attilla [Attilla@FBC920.DDABA2.60661C.0EE0F8] has joined #code |
09:26 | | mode/#code [+o Attilla] by Reiver |
10:02 | | You're now known as TheWatcher |
10:48 | | AnnoDomini [annodomini@Nightstar-1ef8ddec.adsl.tpnet.pl] has joined #code |
10:48 | | mode/#code [+o AnnoDomini] by Reiver |
11:12 | | gnolam [lenin@Nightstar-38637aa0.priv.bahnhof.se] has joined #code |
12:34 | | You're now known as TheWatcher[afk] |
14:16 | | AbuDhabi [annodomini@Nightstar-aa522706.adsl.tpnet.pl] has joined #code |
14:18 | | AnnoDomini [annodomini@Nightstar-1ef8ddec.adsl.tpnet.pl] has quit [Ping timeout: 121 seconds] |
14:44 | | celticminstrel [celticminstre@Nightstar-f8b608eb.cable.rogers.com] has joined #code |
15:48 | | Tarinaky [Tarinaky@Nightstar-06637221.adsl.virginmedia.net] has quit [Operation timed out] |
16:03 | | Tarinaky [Tarinaky@Nightstar-711a2847.adsl.virginmedia.net] has joined #code |
16:03 | < Tarinaky> | ... Did any of what I say get through? |
16:03 | < Tarinaky> | Or was it lost in the ether? |
16:04 | <@TheWatcher[afk]> | Haven't seen anything from you today |
16:05 | < Tarinaky> | http://www.youtube.com/watch?v=gHNRM3V1dWw << Strange bug, code >> http://tarinaky.pastebin.com/m4074b42b |
16:05 | < Tarinaky> | Video quality is terrible but it should show enough. |
16:08 | < Tarinaky> | Oh wait. |
16:08 | < Tarinaky> | I'm a muppet. |
16:08 | < Tarinaky> | Hahahaha. |
16:08 | < Tarinaky> | I see exactly what's wrong. |
16:08 | < Alek> | ahuh. |
16:08 | < Tarinaky> | Cheers anyway. |
16:09 | < Alek> | who's the one with their hand up your arse? >_> |
16:09 | | * Alek flrrd. |
16:09 | < Tarinaky> | Alek: IDGI? |
16:09 | < Alek> | ? |
16:09 | < Tarinaky> | "<Alek> who's the one with their hand up your arse? >_>" ? |
16:23 | | You're now known as TheWatcher |
16:32 | < Tarinaky> | Now I just need to work out how to get this window to draw :/ |
16:44 | < Tarinaky> | http://tarinaky.pastebin.com/m7ede27fe << Can anyone tell me why this isn't drawing the window? |
17:14 | < gnolam> | http://rpi.edu/~calhop/blag/fourier.png |
17:15 | | You're now known as TheWatcher[afk] |
17:16 | <@TheWatcher[afk]> | ... that's bad. |
17:35 | | Rhamphoryncus [rhamph@Nightstar-a62bd960.abhsia.telus.net] has joined #code |
17:57 | | MyCatVerbs [mycatverbs@Nightstar-f43ca811.blueyonder.co.uk] has quit [Operation timed out] |
18:14 | | Derakon[AFK] is now known as Derakon |
18:20 | | Alek [omegaboot@Nightstar-3f3964f1.emhril.sbcglobal.net] has quit [Client closed the connection] |
18:28 | | Alek [omegaboot@Nightstar-3f3964f1.emhril.sbcglobal.net] has joined #code |
18:37 | | You're now known as TheWatcher |
18:42 | | * AbuDhabi scratches head. |
18:43 | < AbuDhabi> | In order to use the global objects declared in the main.cpp file, I also need to put the functions using them in main.cpp, or else I get more errors than I can shake a stick at. |
18:44 | < AbuDhabi> | Is there anything I can do to get around this? |
18:44 | <@Derakon> | Don't put the global object declarations in a .cpp file. |
18:44 | <@Derakon> | Put them in a .h file and then #include the .h file in code files that need access to the objects. |
18:45 | < AbuDhabi> | I'll try that~! |
18:45 | < AbuDhabi> | -~ |
18:48 | < Tarinaky> | How can I draw a '·' in NCurses? Apparently there's meant to be a set of constants I'm supposed to use but they aren't documented. |
18:48 | <@Derakon> | It's been ages since I've done serious C++ coding. |
18:49 | < AbuDhabi> | It worked. Thanks. :D |
19:00 | | Zedidiah [zag@Nightstar-d0088b95.or.comcast.net] has quit [Ping timeout: 121 seconds] |
19:09 | | Zedidiah [zag@Nightstar-d0088b95.or.comcast.net] has joined #code |
19:19 | < AbuDhabi> | I'm getting multiple definition errors now, if I try to #include "globals.h" in another file. |
19:19 | < AbuDhabi> | Help? |
19:20 | <@TheWatcher> | You should onlye be declaring in headers, defining once in one file |
19:21 | < Tarinaky> | AbuDhabi: Use include guards. |
19:21 | < Tarinaky> | #ifndef GLOBALS_H_ |
19:21 | < Tarinaky> | #define GLOBALS_H_ |
19:21 | < Tarinaky> | #endif |
19:22 | < Tarinaky> | That way if you accidentally include a file twice it'll ignore it the second time. |
19:22 | <@TheWatcher> | for example, if you have a variable 'foo' then in a.c you have 'int foo;', in a.h you have 'extern int foo;' and then you can include a.h elsewhere and be fine. |
19:22 | < AbuDhabi> | TheWatcher: I don't understand. I have the declaration of object instances in globals.h. The definitions of these objects are in there separate cpp and h files. |
19:23 | < AbuDhabi> | Tarinaky: I already use them. IN EVERYTHING. |
19:23 | < Tarinaky> | The compiler should tell you where there are two conflicting declarations. |
19:23 | < AbuDhabi> | These are deFINItion errors, not declaration. |
19:24 | < Tarinaky> | The compiler should tell you where there are two conflicting definitions. |
19:24 | < AbuDhabi> | It's pointing at the place where they were earlier, but now they're not. |
19:25 | < Tarinaky> | Does anyone know if it's possible to call git from within gdb? |
19:26 | <@TheWatcher> | AbuDhabi: are you sure you've removed the old objects and recompiled them all? |
19:26 | < AbuDhabi> | Both line-pointers from the compiler point to function definitions, but it say it's about instances of objects. I think it may be telling me where I'm #including "globals.h", which would make some more sense. |
19:27 | | * Derakon mutters at VirtualBox's shared-folder system. |
19:27 | <@Derakon> | I've told it to make a folder shared, but I can't seem to access it from within XP. It says it can't find \\vboxsvr\vboxshare ("vboxshare" being the name of the folder) |
19:28 | < AbuDhabi> | TheWatcher: I'll remove the old objects and recompile. |
19:28 | < AbuDhabi> | Same error. |
19:28 | < AbuDhabi> | It's a linker error, I think. |
19:29 | < AbuDhabi> | Since it complains about .o files. |
19:29 | <@TheWatcher> | Without seeing code and the errors, I'm not sure what else we can suggest |
19:33 | < AbuDhabi> | main.cpp: http://pastie.org/781036 |
19:33 | < AbuDhabi> | utils.cpp: http://pastie.org/781037 |
19:33 | < Alek> | <Tarinaky> I'm a muppet. |
19:33 | < AbuDhabi> | errors: http://pastie.org/781038 |
19:33 | < Alek> | get it yet? |
19:33 | | * Alek pokes Taki. |
19:33 | < Tarinaky> | Alek: Oh. |
19:33 | < Tarinaky> | Alek: I do now. |
19:33 | < Alek> | XD |
19:34 | < AbuDhabi> | Also, globals.h: http://pastie.org/781039 |
19:35 | <@TheWatcher> | AbuDhabi: in globals.h stick extern infront of lines 7, 8, and 9 |
19:36 | < celticminstrel> | I think the problem is that, for variables, the declaration is the definition (unless extern is included). |
19:36 | <@TheWatcher> | then in, say, main.cpp put the same lines without the externs just after the includes |
19:36 | <@TheWatcher> | then recompile and relink it all |
19:36 | < celticminstrel> | Yeah, that'd work. |
19:37 | <@TheWatcher> | The problem is that each file that includes globals.h creates its own copy of map, you, and messageDevice |
19:37 | <@TheWatcher> | and then when the linker goes to work is sees multiple copies of them and freaks |
19:39 | < AbuDhabi> | Should I remove the include for globals.h in main.cpp, then? |
19:39 | <@TheWatcher> | Nope, you can leave it |
19:40 | < AbuDhabi> | Seems to work either way. |
19:40 | < AbuDhabi> | What does extern do, anyway? |
19:40 | <@TheWatcher> | Tells the compiler that a variable is defined somewhere else. |
19:42 | <@TheWatcher> | Say in the case of utils.cpp, it includes the globals.h and sees 'extern You you;', so the compiler knows that you exists and is a You, but doesn't know where it is at that point |
19:42 | < AbuDhabi> | Cool. Thanks! |
19:42 | <@TheWatcher> | in main.cpp, it includes globals and sees the same extern, but then it runs into the actual definition of you as it goes through the code |
19:43 | <@TheWatcher> | then, when the linker comes along, it sees that utils.o is looking for you, and main.o actually declares it, so it can sort out all the references to you in utils.o to go to the correct place |
20:23 | < AbuDhabi> | Is it wrong of me to write and use a utility function that converts a char array into an std::string? |
20:23 | <@Derakon> | Yes, because you should be able to just do std::string(yourCharArray) |
20:27 | < AbuDhabi> | Thanks. |
20:34 | | Zedidiah [zag@Nightstar-d0088b95.or.comcast.net] has quit [Ping timeout: 121 seconds] |
20:34 | | * TheWatcher also suggests looking at bstring rather than std::string - http://bstring.sourceforge.net/ |
20:43 | < AbuDhabi> | Are there real benefits of using it for a project like mine? |
20:51 | | Zedidiah [zag@Nightstar-d0088b95.or.comcast.net] has joined #code |
21:06 | | Syloqs-AFH [Syloq@NetworkAdministrator.Nightstar.Net] has quit [Ping timeout: 121 seconds] |
21:09 | | * Derakon mutters at VirtualBox. |
21:09 | <@Derakon> | Finally got the shared folder working, which allowed me to transfer FCEUX (an NES emulator) to the Windows VM...and then FCEUX crashes immediately on startup. |
21:17 | < AbuDhabi> | Is it possible to use previously defined values in further defines? |
21:18 | < Vornicus-Latens> | Sure, so long as you aren't redefining. |
21:18 | < Vornicus-Latens> | Though, you should evaluate whether a define is really more useful than const. |
21:19 | < AbuDhabi> | It is. I have two separate classes using the same values. |
21:20 | < Vornicus-Latens> | I still don't see how that invalidates using const globals... |
21:21 | < AbuDhabi> | I thought you meant, like, a local const. |
21:22 | < AbuDhabi> | Is there a reason to use consts rather than defines? |
21:24 | <@TheWatcher> | http://www.parashift.com/c++-faq-lite/newbie.html#faq-29.7 |
21:24 | < celticminstrel> | Yes. |
21:24 | < celticminstrel> | A const variable is type-checked. |
21:24 | < Vornicus-Latens> | YOu don't need to be as careful with it; larger objects made define show up many times whereas using const they only exist once |
21:25 | < Vornicus-Latens> | THey're type-checked, they don't give you shit about parentheses. |
21:25 | < celticminstrel> | If you your #define is just a value, a const variable is better. |
21:25 | < celticminstrel> | You should only use #define for actual macros, and that as little as possible. |
21:25 | <@TheWatcher> | (And if your define isn't just a value, inline functions are better) |
21:25 | < celticminstrel> | If it's a calculation, yes. |
21:28 | | * AbuDhabi changes those defines into consts, then. |
21:45 | <@Derakon> | Hmm...perhaps FCEUX isn't happy because of the VirtualBox graphics driver. |
21:45 | <@Derakon> | Given that Spelunky complains about that. |
21:49 | < AbuDhabi> | Hmm. I'm looking to associate a list of names, numbers and chars. What structure in C++ would I use to do this? Struct? Class? Enum? Something else? |
21:49 | < AbuDhabi> | This is for a library of tiles. |
21:51 | < celticminstrel> | What kind of association? |
21:52 | <@Derakon> | You want a heterogenous list? |
21:52 | < celticminstrel> | For a heterogenous list, a union works. It's not the best solution, but it works. |
21:52 | < celticminstrel> | An anonymous union wrapped in a struct, of course. |
21:53 | <@Derakon> | I don't think I understand the question very well, but I'm inclined to implement a class when in doubt. |
21:53 | < celticminstrel> | But I don't think that's what he wanted? |
21:53 | <@McMartin> | While I'm a fan of Tagged Unions, if you're using C++ you might as well reverse the polarity and use virtual functions instead. |
21:53 | < celticminstrel> | Huh? |
21:53 | <@McMartin> | But if he's associating, isn't that std::map? |
21:53 | < celticminstrel> | Reverse the polarity? |
21:53 | < celticminstrel> | Yeah, that part suggests std::map. |
21:54 | <@McMartin> | With a tagged union U, you write f(U *x), g(U *x), etc. and each of those checks the tag to see what to do. |
21:54 | <@McMartin> | You may as well in C++ just have a superclass that does f(), g(), etc. and have the different "tags" become different subclasses. |
21:55 | < celticminstrel> | I suppose you could...? |
21:55 | < AbuDhabi> | I'm thinking that each number and name should be unique, but the char doesn't have to be. |
21:55 | < celticminstrel> | Are you saying you basically want a database? |
21:55 | < AbuDhabi> | Well, sorta. |
21:56 | < AbuDhabi> | I want to do something like Tiles.getNumber("WALL") or something where the number counts and I don't want to memorize what the numbers mean. |
21:57 | < Vornicus-Latens> | Use a map for that. |
21:57 | < celticminstrel> | What is the char for, then? |
21:57 | < Vornicus-Latens> | Or an enum, if you want it to be the same forever. |
21:57 | < AbuDhabi> | celticminstrel: The graphical representation. |
21:57 | <@Derakon> | Hm. I'm using VirtualBox 2.1.4, and they're up to 3.1.2. Maybe I should upgrade~ |
21:57 | < celticminstrel> | Okay. |
21:57 | < celticminstrel> | Here's my suggestion. |
21:59 | <@Derakon> | Oh, goddammit. And that version of VirtualBox doesn't support OSX 10.4. >.< |
22:00 | <@Derakon> | It's only four years old! |
22:00 | <@Derakon> | (The OS, that is) |
22:00 | | * Derakon mutters. |
22:00 | < celticminstrel> | Suppose you have tiles WALL (0, #), GRASS (1, *) and WATER (2, w). Create an "enum tiletype {WALL = 0, GRASS = 1, WATER = 2,};", then declare an std::map<tiletype,char>. (Note: the initialization is optional, but it may be a good idea in certain situations.) |
22:00 | | Syloqs_AFH [Syloq@NetworkAdministrator.Nightstar.Net] has joined #code |
22:01 | | Syloqs_AFH is now known as Syloqs-AFH |
22:06 | < AbuDhabi> | Hmm. |
22:07 | <@McMartin> | 10.4 is missing a *lot* of fairly basic stuff~ |
22:08 | <@McMartin> | For that matter, so is 10.5 |
22:08 | < celticminstrel> | What's missing? |
22:08 | <@McMartin> | (For *that* matter, so is 10.6) |
22:08 | <@Derakon> | So that's not really much help then, is it? |
22:08 | < AbuDhabi> | celticminstrel: How do I use a map? I've never used them before? |
22:08 | <@Derakon> | I mostly just don't want to have to pay for an OS upgrade just to support more software. ¬.¬ |
22:08 | < celticminstrel> | AbuDhabi: It's a lot like an array, except the indices are not numbers. |
22:08 | <@McMartin> | Derakon: It means that upgrades are likely to break things because people will use the ability to, for example, actually programmatically configure their printers. |
22:09 | < celticminstrel> | To add something to the map, you'd use "tiles[WALL] = '#';". |
22:09 | <@McMartin> | (partially in 10.4, generically in 10.5, "oh, you mean you wanted *different* settings for *different* printers" in 10.6, still missing "I'd like to set *actual global defaults* without hacking CUPS's config files") |
22:10 | <@Derakon> | ...hang on. |
22:10 | < AbuDhabi> | celticminstrel: How do I declare it? It's erroring about missing constructors or something? |
22:10 | <@Derakon> | Educational discount puts Snow Leopard at $30. |
22:10 | <@Derakon> | So, uh, yeah. Maybe I should buy that. |
22:10 | <@McMartin> | Yes~ |
22:11 | < celticminstrel> | #include <map> |
22:11 | < celticminstrel> | std::map<type1,type2> mymap; |
22:11 | <@McMartin> | Assuming you have an Intel Mac in the first place. |
22:11 | <@Derakon> | I have an '05 iMac. |
22:11 | <@McMartin> | Adding stuff to maps is a little wacky. |
22:11 | <@McMartin> | Because, IIRC, referencing a map with [] will create the element if it didn't exist before. |
22:11 | < celticminstrel> | Not really. You use array indices. |
22:11 | < celticminstrel> | Yes, that's true. But usually that's what you want, right? |
22:11 | <@McMartin> | And will use operator= after default constructor. |
22:11 | <@McMartin> | That is almost never what *I* want. |
22:11 | < celticminstrel> | Huh? |
22:12 | <@McMartin> | I want "does this exist, if so, give it to me, otherwise flag 'does not exist'" |
22:12 | <@McMartin> | If I say a = foo["WAL"], I want it to tell me "foo has no 'WAL'", not "Right-o! Here you go then". |
22:12 | < celticminstrel> | Then you'd query the map before accessing it. I'm pretty sure there's a "has key" function. |
22:12 | <@McMartin> | Yes. |
22:13 | <@McMartin> | Has-key in fact returns the element that's there, too. |
22:13 | <@Derakon> | He's saying that it shouldn't have to be explicit. |
22:13 | <@Derakon> | operator[] should throw an exception if the element is missing. |
22:13 | <@McMartin> | No, I'm saying "the explicit assign and lookup operators are all I use." |
22:13 | <@Derakon> | Ah. |
22:13 | < celticminstrel> | No, operator[] should not throw an exception. |
22:14 | < celticminstrel> | Unless the compiler can distinguish properly between when it's used to access and when it's used to set. |
22:14 | <@McMartin> | And yeah, operator[] *cannnot* return it becaues of that. |
22:14 | <@McMartin> | Which is *should*, in fact, be able to do. |
22:14 | <@McMartin> | But cannot. |
22:14 | < AbuDhabi> | Oh, crap. The map type is conflicting with the instance name for my Map... I think. |
22:14 | <@ToxicFrog> | operator[] is called for both set and get? |
22:14 | <@McMartin> | Yes. |
22:14 | <@McMartin> | a['foo'] = "bar" does this: |
22:14 | <@McMartin> | Looks up a['foo'], finds it's not there, creates a new one, returns a reference to it. |
22:14 | <@McMartin> | Calls operator= on that reference with "bar" |
22:14 | < celticminstrel> | There are two operator[]'s (a const and non-const), but I don't think they'd be distinguished correctly. |
22:14 | <@Derakon> | AbuDhabi: yeah, make it TileMap or GameMap or something. |
22:14 | <@Derakon> | Generic names are oftentimes a bad idea. |
22:15 | <@Derakon> | I had some horrible problems once because I named a Python module "platform.py". |
22:15 | <@McMartin> | celticminstrel: that's so that you can still do lookups on const maps, which you would otherwise be unable to do. |
22:15 | <@McMartin> | What with it modifying the map and all. |
22:15 | <@McMartin> | In fact, I'm not sure if you are even allowed to do it on const maps anyway because of that. |
22:16 | < celticminstrel> | Can't the compiler tell whether an expression is being used as an l-value? |
22:16 | <@McMartin> | Yes, but that isn't what const means. |
22:16 | < celticminstrel> | It's what & means. |
22:17 | <@ToxicFrog> | McMartin: these assignment semantics are very weird to me. |
22:17 | < celticminstrel> | ...it's pretty normal for maps. |
22:17 | <@McMartin> | TF: lolSTL. |
22:17 | <@McMartin> | celticminstrel: It is *not* normal for "read" operations to increase the size of your map. For serious. |
22:17 | < celticminstrel> | It works the same way in Python, for example. At least, as far as the end result is concerned. |
22:17 | <@McMartin> | No other language does this. |
22:17 | < AbuDhabi> | What if I wanted to add more elements that are mapped? Like, properties of certain tiles, like walkability, submergence, inherent hostility? |
22:17 | <@McMartin> | No. |
22:18 | <@McMartin> | Python throws KeyError. |
22:18 | < celticminstrel> | Oh, wait. |
22:18 | <@McMartin> | http://cplusplus.com/reference/stl/map/operator%5B%5D/ |
22:18 | <@McMartin> | The operation on mymap['d'] in the sample code? Unique to C++. Deeply unintuitive. |
22:18 | <@McMartin> | Full of nasty gotchas if you typo your keys. |
22:18 | < celticminstrel> | No it doesn't throw KeyError. |
22:18 | <@McMartin> | Because it's not an error, you were just asking for something eles. |
22:19 | < celticminstrel> | It only does that if you're trying to access the key. Not when you're setting it. |
22:19 | <@McMartin> | >>> a = {'x':3} |
22:19 | <@McMartin> | >>> a['x'] |
22:19 | <@McMartin> | 3 |
22:19 | <@McMartin> | >>> a['y'] |
22:19 | <@McMartin> | Traceback (most recent call last): File "<stdin>", line 1, in <module> |
22:19 | <@McMartin> | KeyError: 'y' |
22:19 | <@McMartin> | >>> |
22:19 | <@McMartin> | Yes, that's the point. |
22:19 | <@McMartin> | In C++, accessing a nonexistent key creates it. |
22:19 | <@McMartin> | This is Wacky(tm). |
22:20 | <@ToxicFrog> | celticminstrel: yes, it's access we're talking about |
22:20 | < celticminstrel> | So, what it needs is a way to distinguish between accessing and setting. |
22:20 | <@ToxicFrog> | This is not "pretty normal for maps" in any language I've used maps in. |
22:20 | < celticminstrel> | The syntax is. |
22:20 | < celticminstrel> | I was referring to the syntax. |
22:20 | <@ToxicFrog> | Yes, but we are not talking about the syntax, we're talking about the semantics! |
22:20 | < celticminstrel> | Okay then! |
22:20 | <@ToxicFrog> | Hence me saying "semantics" rather than "syntax" |
22:20 | <@McMartin> | And the normal semantics are afforded by the use of map::insert and map::find. |
22:20 | <@ToxicFrog> | To which you replied with "it's pretty normal for maps" |
22:21 | <@McMartin> | map::insert and a[x] = y are very, very different operations, though. |
22:21 | < celticminstrel> | I guess I wasn't paying close enough attention. Sorry. |
22:21 | < celticminstrel> | But map::insert is ugly. |
22:22 | < celticminstrel> | You need to do mymap.insert(std::make_pair(key,val)); |
22:22 | <@McMartin> | You also need to make sure that key isn't already there, if you want to overwrite. |
22:23 | < celticminstrel> | Insert doesn't overwrite? |
22:23 | <@McMartin> | No |
22:23 | <@McMartin> | In fact, I'm not positive, but I think insert doesn't even copy. |
22:26 | <@McMartin> | I think it's a direct reference to the object in the pair if not the pair itself |
22:26 | <@McMartin> | cplusplus.com's reference pages are your tiny gods for dealing with STL corners, though. |
22:27 | <@ToxicFrog> | See, not copying is what I would expect |
22:28 | <@McMartin> | TF: Tricky for maps. Keys are supposed to be copied, and with lack of garbage collection, copying for elements is important in case your keys/values don't escape. |
22:28 | <@ToxicFrog> | ...right. Not a garbage-collected language. |
22:28 | | * ToxicFrog has been working in HLLs for a while, can you tell? |
22:29 | < Namegduf> | Insert copies. |
22:29 | <@McMartin> | Depending on your object, you may have the "value" actually be a pointer, and insist that the map owns all its elements and nobody lets values escape |
22:29 | < Namegduf> | Unless you insert pointers. |
22:29 | < Namegduf> | I think. |
22:29 | <@McMartin> | The values are always going to be copied by value |
22:30 | < Namegduf> | Right. |
22:30 | <@McMartin> | Er, the pointers |
22:30 | <@McMartin> | They're a primitive type |
22:32 | | * TheWatcher readsup |
22:32 | <@TheWatcher> | Dera: um, wait, what max do you have? |
22:32 | <@TheWatcher> | *mac |
22:33 | <@TheWatcher> | For some reason I seem to remember you have an iMac G5? |
22:38 | <@McMartin> | That's Vorn, I think |
22:38 | <@TheWatcher> | Oh, 'kay. |
22:39 | < AbuDhabi> | gnolam: Does Code::Blocks have something that auto-generates setters/getters? |
22:39 | < AbuDhabi> | I find myself using a mIRC script for that dreary task. |
22:40 | < celticminstrel> | I think setters/getters are overrated. They're useful for restricting access to write-only or read-only, and they're useful for validating input, but for some things they're just pointless. |
22:42 | < Vornicus-Latens> | No, I do not have a g5. |
22:42 | < Vornicus-Latens> | I /had/ a g4 |
22:45 | < celticminstrel> | Is it silly to use a while loop when you're 99.9% sure it will only execute once? |
22:46 | < Vornicus-Latens> | No. |
22:46 | < Vornicus-Latens> | Because sometimes it won't. |
22:48 | < AbuDhabi> | Can I use a struct type for a map? |
22:48 | < celticminstrel> | Maybe. It really depends what you want. |
22:49 | <@McMartin> | if the struct type is std::string, absolutely |
22:49 | < AbuDhabi> | I want more things associated with a tile, rather than just the char. |
22:49 | < celticminstrel> | Well, you could map to a tile_info struct if you wanted to. |
22:49 | < celticminstrel> | Instead of a char. |
22:50 | <@McMartin> | Just remember that every value has to be the same type, and if they aren't pointers, this doesn't include subclasses. |
22:50 | < celticminstrel> | Hm? |
22:51 | <@McMartin> | If you have map <K, V1> m, and a class V2 : public V1, you can in fact write m[k] = V2(...). |
22:51 | <@McMartin> | *HOWEVER* |
22:51 | <@McMartin> | What will go *into* the map is a V1 copy-constructed from that V2. |
22:51 | <@McMartin> | This is called "slicing". It's bad~ |
22:51 | < celticminstrel> | Ah yes. If they aren't pointers. Right. |
22:52 | < celticminstrel> | I need to read more carefully. |
22:52 | <@McMartin> | You may want to make your map be something like map<std::string, boost::shared_ptr<GameObject> >. |
22:53 | < celticminstrel> | It's not really necessary to use pointers unless it's a base class, though. |
22:53 | <@McMartin> | Yeah, but if you're having a universal resource map, or if resources can take subtypes for variation... |
22:54 | < AbuDhabi> | I'm not anticipating they will have subtypes. |
22:54 | | * Vornicus-Latens determines that he has hatred for C++, just from this discussion. |
22:54 | < AbuDhabi> | Damn. |
22:55 | < celticminstrel> | I like C++. |
22:55 | < AbuDhabi> | std::map<tiletype,Tile> mymap; results in "s Roguelike\main.cpp|20|error: expected a type, got `Tile'|" |
22:55 | < celticminstrel> | So, Tile is not a type? |
22:55 | <@McMartin> | That sounds like the class "Tile" hasn't been defined yet. |
22:55 | <@McMartin> | C++ lets you do everything a hundred different ways, and 99 of them are wrong~ |
22:56 | < celticminstrel> | Hehe. |
22:56 | <@McMartin> | Sometimes all 100, but those are for the cases where you can't ever do it right in the first place (hi, multiple inheritance) |
22:56 | < Namegduf> | Perl lets you do them 200, and all of them are ugly. :P |
22:56 | | Syloqs-AFH [Syloq@NetworkAdministrator.Nightstar.Net] has quit [Ping timeout: 121 seconds] |
22:56 | < AbuDhabi> | Tile is a struct that's defined in a .h file that I include. |
22:56 | < celticminstrel> | I kind of like the existence of multiple inheritance... not that I use it a lot though. |
22:57 | <@McMartin> | AbuDhabi: You should really replace "struct" with "class {public:" |
22:57 | < celticminstrel> | Is there an error in Tile's definition? |
22:57 | < celticminstrel> | I disagree with that, McMartin. |
22:57 | <@McMartin> | Well, it's a style thing. |
22:58 | <@McMartin> | If "struct Tile" works instead of "Tile", though... |
22:58 | < celticminstrel> | If that works, then there's something else that's also called Tile. |
22:58 | <@McMartin> | We've already seen this with "map" today. |
22:58 | < AbuDhabi> | Okay, with a class instead of a struct, it compiles correctly. |
22:59 | < celticminstrel> | ...what? How? |
22:59 | <@McMartin> | (re: MI, it's the case where you have class A, class B : A, class C : A, and class D : B, C that forces you to make a choice about how to render the object layout, and both of them are wrong in some circumstances.) |
22:59 | <@McMartin> | (So C++ repurposes the "virtual" keyword to let you pick which way.) |
23:00 | < celticminstrel> | Indeed. |
23:02 | <@McMartin> | (That said, virtual MI is always a bad idea even when it's technically correct~) |
23:03 | < AbuDhabi> | Remind me, an enum works pretty much like declaring constants/defines, but saves you some syntax work? |
23:03 | < celticminstrel> | Pretty much, yes. |
23:03 | < celticminstrel> | Plus it only allows integer constants. |
23:04 | <@McMartin> | They also allow a degree of typechecking in C++, I think. |
23:06 | < celticminstrel> | Yes, it won't allow you to convert between two different enum types without a cast. |
23:07 | < AbuDhabi> | So, again, to add something to my map called 'tiles', having an enum element 'WALL' and an instance of Tile called 'wall' I go 'tiles[WALL] = wall'. Did I get that right? |
23:07 | <@McMartin> | That should do it. |
23:07 | <@McMartin> | In fact, with that, you can use a std::vector. |
23:07 | < AbuDhabi> | What are the benefits? |
23:08 | <@McMartin> | Faster access, more efficient memory usage. |
23:08 | < AbuDhabi> | And no wackiness? |
23:08 | <@McMartin> | More "different kinds of wackiness", but less surprising kinds. |
23:10 | <@McMartin> | If you use [] and pass an illegal value, Wackiness Ensues. |
23:10 | <@McMartin> | If you use at, it will throw. |
23:10 | < AbuDhabi> | Well, I can live with that. |
23:11 | < AbuDhabi> | How do you declare a vector? |
23:11 | <@McMartin> | http://cplusplus.com/reference/stl/vector/ |
23:11 | < celticminstrel> | There's also a Boost.Multiarray, which might be useful for a grid of tiles. |
23:12 | <@McMartin> | The way you'd want to do it here is "std::vector<Tile> tiles(MAX_TILES)" |
23:12 | < celticminstrel> | I think that's what it's called, anyway. |
23:12 | <@McMartin> | Where MAX_TILES is the last member of your TILES enum. |
23:12 | <@McMartin> | Tile will need a default constructor that shouldn't do much; then you can iterate through the vector and initialize it at will. |
23:12 | < celticminstrel> | ...yes, that would work. I guess you weren't talking about what I thought you were. XD |
23:12 | < celticminstrel> | Tile already has a default constructor. |
23:13 | <@McMartin> | If you expect the tile set to be constant throughout the run of the program you could even use a C array, but C++ programmers will generally suggest you never use them and it's hard to argue. |
23:13 | < celticminstrel> | It's a POD, isn't it? |
23:13 | <@McMartin> | EAP |
23:13 | < celticminstrel> | ??? |
23:14 | <@McMartin> | "Expand Acronym, Please" |
23:14 | < celticminstrel> | Plain Old Data. |
23:14 | < celticminstrel> | Technically I should have said POD type. |
23:14 | <@McMartin> | Oh, you mean Tile. |
23:14 | <@McMartin> | I wasn't paying attention that early |
23:14 | <@McMartin> | In fact, it's 3 an dI haven't had lunch yet. |
23:14 | | * McMartin goes to fix this. |
23:14 | < AbuDhabi> | ... |
23:14 | < AbuDhabi> | An array of Tile. |
23:14 | | * AbuDhabi facepalms. |
23:15 | < AbuDhabi> | Why didn't I think of this in the first place? |
23:15 | < celticminstrel> | Because you weren't using an enum? |
23:15 | <@McMartin> | As a rule in C++, std::vector should be used in place of arrays when possible. |
23:15 | <@McMartin> | The extra checking and the sensible handling of destructors is worth the space cost. |
23:16 | < celticminstrel> | What about std::deque? |
23:16 | <@McMartin> | Depends on why you need the array. This one's pretty clearly random access, so deque is out. |
23:16 | < celticminstrel> | I've been given the impression that it's not much different than a vector. |
23:16 | | * McMartin checks |
23:16 | <@McMartin> | Hmm. |
23:17 | < celticminstrel> | It's usually stored sequentially, right? As opposed to a linked list? |
23:17 | <@McMartin> | Actually checking now |
23:17 | < AbuDhabi> | I'm looking at the documentation, and I still don't have a clue how to use vectors. |
23:17 | < celticminstrel> | It's not as optimized for random access, though, if I recall correctly. |
23:17 | | * AbuDhabi is tired. |
23:17 | <@McMartin> | It's roughly the same for random access |
23:17 | < celticminstrel> | AbuDhabi: You use vectors in the same way as you use arrays. |
23:17 | < AbuDhabi> | Except? |
23:17 | <@McMartin> | What it isn't is contiguous in memory, so you can't impedance-match to C. |
23:18 | <@McMartin> | (Also, push_front exists on deques.) |
23:18 | < celticminstrel> | And you use myvec.size() to get the size of the vector. |
23:18 | < celticminstrel> | "impedance-match"? |
23:18 | <@McMartin> | And you don't have to dick around with new[] and delete[] |
23:18 | <@McMartin> | celticminstrel: You can, with an std::vector<char>, do something like pass &vec[0] to strcpy. and have it act like a char*. This isn't true for a deque. |
23:19 | < celticminstrel> | Oh. I thought it was (at least in some implementations). |
23:19 | <@McMartin> | "unlike vectors, deques are not guaranteed to have all its elements in contiguous storage locations, eliminating thus the possibility of safe access through pointer arithmetics. |
23:19 | < AbuDhabi> | vector<int> tiles; tiles[WALL] = wall; // how much of this is wrong? |
23:20 | <@McMartin> | The <int> |
23:20 | <@McMartin> | wall is presumably of type "Tile" or some such |
23:20 | <@McMartin> | That makes it a vector<Tile> |
23:20 | < celticminstrel> | AbuDhabi: You have to do tiles.append(wall); |
23:20 | <@McMartin> | Alternately, you can pre-size it. |
23:20 | < celticminstrel> | You use [] only for accessing or changing elements, not for inserting them |
23:21 | <@McMartin> | vector<Tile> tiles(MAX_TILES); tiles[WALL] = wall; should work. |
23:21 | <@McMartin> | (if using namespace std) |
23:21 | < celticminstrel> | Yes. |
23:21 | < AbuDhabi> | (I am.) |
23:21 | <@McMartin> | I'd recommend against append here because then you have to insert the tiles in numerical order, which defeats much of the gains from having the enum in the first place. |
23:21 | <@McMartin> | But both will work. |
23:23 | | celticminstrel [celticminstre@Nightstar-f8b608eb.cable.rogers.com] has left #code [] |
23:24 | < AbuDhabi> | Also, where would I put all of this, if I wanted to reduce clutter in main.cpp? |
23:25 | < AbuDhabi> | Mumble. "enum tiletype {WALL = 1, GRASS = 2, WATER = 3}; vector<Tile> tiles(ROGUELIKE_MAXTILES); Tile wall; tiles[WALL] = wall;" is causing "s Roguelike\main.cpp|22|error: expected constructor, destructor, or type conversion before '=' token|" |
23:38 | | You're now known as TheWatcher[T-2] |
23:44 | | You're now known as TheWatcher[zZzZ] |
23:45 | < AbuDhabi> | I'm not sure I can just make a .cpp file, plop some code in there, and include it or something. |
--- Log closed Sun Jan 17 00:00:12 2010 |