|
I know, and I don't really want to post those as it gets into "having other people do your homework" territory. I appreciate the suggestions though, thanks Edit: I figured it out! I took all the re declared private members out of my child class, and used the methods that I already had to just use the private variables in my parent class. It seems super obvious now and I feel dumb for not seeing it sooner. But still, thanks again for the help, everyone! WHERE MY HAT IS AT fucked around with this message at 22:10 on Mar 21, 2013 |
# ? Mar 21, 2013 21:53 |
|
|
# ? Jun 8, 2024 08:13 |
|
Looking for suggestions on how to implement this in the least lovely way possible.code:
The above is the closest I've gotten to what I want, but I'd really prefer not to have to cast the input every time plus it kind of breaks polymorphism.
|
# ? Mar 21, 2013 22:57 |
|
What would you intend to happen if you passed the wrong kind of derived class Structure to the function, and if the answer is "it wouldn't work", then what's the point of the function being virtual at all? If the answer is "it wouldn't compile" you might want templates rather than inheritance
seiken fucked around with this message at 23:07 on Mar 21, 2013 |
# ? Mar 21, 2013 23:03 |
|
seiken posted:What would you intend to happen if you passed the wrong kind of derived class Structure to the function, and if the answer is "it wouldn't work", then what's the point of the function being virtual at all? If the answer is "it wouldn't compile" you might want templates rather than inheritance I want polymorphism so I can do stuff like code:
The actual contents of the interface(s) are freely modifiable, I just want to enforce the ability to tie a certain struct definition to a certain class as close to compile time as possible. dragon enthusiast fucked around with this message at 23:32 on Mar 21, 2013 |
# ? Mar 21, 2013 23:28 |
|
Four options: 1. You can use templates, where instead of creating A and B and calling a virtual method on A, you template all the code between the point you create A and B and the point at which you start passing B to A's methods. 2. You can use encapsulation, where B holds a properly-typed A or vice-versa. 3. You can switch to a language with a crazily rich type system that can express this directly. I don't know of any that isn't actually a theorem prover. What you want falls within the general category of existential typing. 4. You can do what you're currently doing it and just live with the fact that no, it's not going to be statically type-safe.
|
# ? Mar 22, 2013 00:03 |
|
I kind of think this is an X/Y problem and you should explain what you're actually doing and why you want this because the use case you gave is sort of odd.
|
# ? Mar 22, 2013 00:20 |
|
rjmccall posted:Four options: Without knowing more about the problem, I agree especially with option 1. What it sounds like you are representing is a single concept modeled by multiple different types, and that concept also has an associated type that must model a different concept. This is a perfect case for templates, pending of course that compile-time polymorphic behavior is all you need. If you want an example of this in actual code, it's done in the C++ standard library with containers and iterators. std::vector, std::list, std::deque, etc. are models of the sequence concept, and that concept includes an associated iterator type that models an iterator concept. These containers each have "insert" and "erase" functions that take an instance of the container's corresponding iterator type. Similarly, there are generic algorithms in the standard library that work with any of those iterator types. Further, attempting to use a list's iterator with a vector's "erase" will [in any reasonable implementation] not compile. However, because they all model the same concept, you can still write algorithms that are templates that will work with any of your types. These containers can also be used with the container adaptors such as std::queue. There are no virtual functions or even inheritance directly required to make these containers. All polymorphic behavior is strictly compile-time. It's easy to default to using inheritance and virtual functions whenever you need polymorphic behavior, and for statically typed languages that don't have something that provides analogous behavior to templates there's often not much more that you can do than that, but in C++ I find that it's usually more useful to default to using templates unless you actually need the run-time behavior of virtual functions. The other downside is obviously that templates generally require you to have a bit of a deeper understanding of the language and the error messages are a bit more difficult to read. Edit: To make it more clear, I commented up your code a bit code:
That Turkey Story fucked around with this message at 01:26 on Mar 22, 2013 |
# ? Mar 22, 2013 01:14 |
|
What I want to do is create a class that takes input data, does calculations and poo poo on it, and returns a pointer to the processed output data. The struct in this case is metadata associated with the input data. I wanted the polymorphism aspect because there's a lot of possible stuff I could do with the input data, and it all requires different metadata (and different output structs). But as far as the end user is concered all he needs to do is call process(struct *metaData, inputType *inputData).
|
# ? Mar 22, 2013 02:13 |
I have been idly working on a problem I've had off and on for years and I'm still not sure the easiest way to implement it. The problem relates to parsing streams of data (I do embedded electronics, so say RS232 serial characters, one after another) looking for strings. For example, you have a AT-compatible modem and you are communicating with it. On such a system, you get a hardware generated interrupt every time you receive a character. The interrupt calls a function which can read the character out of a hardware register and do something with it. I think a nice approach to the problem could be an acceptor state machine. The theory is straight forward, but the implementation is killing me. I am trying to use as much standard C as I can, as it is the most widely accepted language for the platforms I work on. I happen to love function pointers, so I made a function for each state that accepts the next character as an argument, and sets the function pointer to the appropriate follow up state for the next character. The concept is easy enough, and it seems like a good fit for my use case. Often times I have plenty of flash (code space) but am limited in both memory and processing time. There are other caveats to keep in mind, but it's mostly corner-case type stuff on particular platforms (hardware stacks!!!! ). The problem I have is generating the necessary code. Take this simple state machine, looking for the strings 'cat', 'hat' and 'hood' in a incoming character stream. I defined a state machine for holding all of my current information: code:
code:
|
|
# ? Mar 23, 2013 00:59 |
|
just a butt posted:What I want to do is create a class that takes input data, does calculations and poo poo on it, and returns a pointer to the processed output data. The struct in this case is metadata associated with the input data. If rjmccall or turkey story disagree then go with whatever they say but I think you're over-engineering this (or still not giving the full story). From what you've said you just want some functions with arbitrary parameter types and semantics to share the same name, which is handled quite well by overloading: C++ code:
seiken fucked around with this message at 01:16 on Mar 23, 2013 |
# ? Mar 23, 2013 01:04 |
Delta-Wye posted:I have been idly working on a problem I've had off and on for years and I'm still not sure the easiest way to implement it. The problem relates to parsing streams of data (I do embedded electronics, so say RS232 serial characters, one after another) looking for strings. As you suggest, you should be generating this code. Commonly, this is known as a parser generator. (Or in your case it looks like just a basic lexer.) You could either use a pre-existing one (e.g. flex, which is a lexer generator) or write your own if existing ones don't work under your constraints. Also, I would really suggest using a table-based approach. Most likely, your function-pointer based approach will use more memory in the end since you need separate machine code for every single state, and each state will need to store multiple full pointers to following states, while with a table-based approach you should be able to get away with storing only the characters you are looking for and an index into your table for the next state. A table-based approach should also be more cache-friendly, I think.
|
|
# ? Mar 23, 2013 01:20 |
|
quote:I have been idly working on a problem I've had off and on What you're describing is essentially a very constrained kind of regular expression engine (with only alternation and concatenation) which should be pretty easy to implement if you look up how.
|
# ? Mar 23, 2013 01:32 |
nielsm posted:As you suggest, you should be generating this code. Commonly, this is known as a parser generator. (Or in your case it looks like just a basic lexer.) You could either use a pre-existing one (e.g. flex, which is a lexer generator) or write your own if existing ones don't work under your constraints. Cache, heh. seiken posted:What you're describing is essentially a very constrained kind of regular expression engine (with only alternation and concatenation) which should be pretty easy to implement if you look up how. Both great. While my friends doing pure CS learned about tokenization et al, I was learning emag. Any chance you'd be willing to gift me a few links or book titles that I can peruse? EDIT: Sorry, that reads a bit more snarky than I intended. Part of my difficulty is I simply don't know the proper terminology for some of this stuff as its outside of my experience. I understand what you mean by "a very constrained kind of regular expression engine (with only alternation and concatenation)", and I would like to look up how, I'm just not sure what the hell to call such a thing. I guess I should get something like this http://www.amazon.com/dp/0521607655/ and read the chapters on lexical analysis and parsing. Delta-Wye fucked around with this message at 01:39 on Mar 23, 2013 |
|
# ? Mar 23, 2013 01:33 |
|
I apologise for not actually being able to recommend a resource that I have personally used, but with some quick googling I found these online lectures on the theory that look pretty decent and this stuff about actual implementation might be useful although some of them are more focused on the speed stuff which you don't need if you're pre-generating this. And you don't need the star operator or any nesting so you don't need half the code also A compilation book, while certainly interesting and valuable, may well skip the foundation regex/finite automata stuff that you really want and go straight to lexing, which is probably more than you need for this problem. edit: I know the dragon book definitely has the automata and regex stuff, but you'd only need like the first chapter Edit again: to clarify, all you need to do to solve your specific problem is precompute a DFA table from e.g. "cat|hat|hood" and use that to process the stream at runtime. seiken fucked around with this message at 02:22 on Mar 23, 2013 |
# ? Mar 23, 2013 01:59 |
|
Delta-Wye posted:The function 'state3' in this case would switch if it gets an 'a' or an 'o' or reset to state0 otherwise. This part can be simplified further. If your state machine knows to handle 'did not match' state changes differently then it can try matching the same input in all states that are an option in this place until one of them matches or the state machine goes to state0. In your example state3 would expect 'a' or something else. If 'a' is not given as input state3 can call state4 straightaway and give the same input it got. Then in state4 if the input is not 'o' it resets to state0.
|
# ? Mar 23, 2013 02:26 |
|
If I return a struct as a const, will its member variables effectively be const too?
|
# ? Mar 24, 2013 17:36 |
jiggerypokery posted:If I return a struct as a const, will its member variables effectively be const too? Uh, I'm not sure that makes sense. A return value can't be const in itself, since it's (formally) a copy of the value returned. You can return a pointer or reference to a const thing, though. Of course that requires the thing to be allocated somewhere else.
|
|
# ? Mar 24, 2013 17:43 |
|
You can, but it doesn't make a lot of sense because you'd be returning a copy anyway. But if you return it as a const reference then yes.
|
# ? Mar 24, 2013 17:44 |
|
The structure in question is part of a private array. I was going to overload [] to allow access to its members but I don't want them to be editable. So you are saying as long as i don't return a reference or pointer I am in the clear yeah?
|
# ? Mar 24, 2013 17:53 |
C++ code:
Bar::get_constref() will return a reference into the private array, but the reference is to a const value so you can't modify the contents of the private array. Bar::get_plainref() will return a non-const reference, so that reference will allow you to modify the contents of the private array. The first two functions are also marked const, since they can't modify the Bar object itself. The first returns a copy, so it's safe. The second returns a const ref, so it's also safe. Any of those functions could of course also be implemented as operator[] instead, I just named them differently for the purpose of this example.
|
|
# ? Mar 24, 2013 18:01 |
|
nielsm posted:Uh, I'm not sure that makes sense. A return value can't be const in itself, since it's (formally) a copy of the value returned. You can return a pointer or reference to a const thing, though. Of course that requires the thing to be allocated somewhere else. You can have a const return type and it is different from a non-const return type. One is a const r-value while the other is a non-const r-value. That said, it's not particularly useful to have a const return type. jiggerypokery posted:The structure in question is part of a private array. I was going to overload [] to allow access to its members but I don't want them to be editable. Yeah. Again, you are returning a copy. Modifying the data will just be modifying a copy of the data that was stored privately.
|
# ? Mar 24, 2013 18:05 |
|
Is there some way to find out which functions take the longest to run so I know what optimizations are most important? EDIT: Also, find out which variables are unused. I'm using VS2010. Boz0r fucked around with this message at 14:03 on Mar 25, 2013 |
# ? Mar 25, 2013 13:14 |
Boz0r posted:Is there some way to find out which functions take the longest to run so I know what optimizations are most important? It's called profiling. The higher-tier editions of Visual Studio have a built-in tool for it, or you can look for third-party tools.
|
|
# ? Mar 25, 2013 14:17 |
|
Boz0r posted:EDIT: Also, find out which variables are unused. I'm using VS2010. I think the VS compiler will emit warnings about unused variables by default. If it isn't look up what the flag is to emit all warnings, in gcc-land it's -Wall.
|
# ? Mar 25, 2013 14:23 |
cliffy posted:I think the VS compiler will emit warnings about unused variables by default. If it isn't look up what the flag is to emit all warnings, in gcc-land it's -Wall. Only for local variables. If you have fields in classes/structs or globals you don't know whether are in use, try commenting them out and see if you get errors compiling
|
|
# ? Mar 25, 2013 14:32 |
|
nielsm posted:Only for local variables. If you have fields in classes/structs or globals you don't know whether are in use, try commenting them out and see if you get errors compiling If you can run it, Clang also has -Wunused-private-field which is pretty neat!
|
# ? Mar 25, 2013 15:08 |
|
I'll see if I can't get a fancy version of VS from the university, thanks.
|
# ? Mar 26, 2013 12:30 |
|
Boz0r posted:I'll see if I can't get a fancy version of VS from the university, thanks. You should be able to get a copy of VS 2012 Professional from DreamSpark.
|
# ? Mar 26, 2013 15:18 |
|
nielsm posted:It's called profiling. Another way to profile your code if you don't have the cash for something nice like Zoom (and aren't running Linux so can't use kcachegrind) is to put scoped timers in your code. They're simple to implement - merely create a class that records the time when it constructs, then logs/prints its lifetime when it destructs. Then just throw it into the first line of a method/function and voila - it'll automatically log the total time spent in that function. It's called a scoped timer because it records the time from instantiation until it goes out of scope (ie. when you exit the function the destructor's called). If you have access to Zoom then I'd recommend that, though - Zoom is great! Goreld fucked around with this message at 22:16 on Mar 26, 2013 |
# ? Mar 26, 2013 22:14 |
|
Why is noexcept better than throw() again, if throwing an exception past it still isn't undefined behavior? edit: I'm asking for a friend
|
# ? Mar 28, 2013 01:52 |
|
Vanadium posted:Why is noexcept better than throw() again, if throwing an exception past it still isn't undefined behavior? The big pluses are the ability to directly specify whether or not a given function can throw an exception based on a compile-time constant (often based on whether or not another expression can throw), and that a noexcept does not need to unwind the stack. The latter makes it possible for callers of noexcept functions to be more optimal than callers of throw() functions in a compliant compiler.
|
# ? Mar 28, 2013 02:15 |
|
Can someone explain what I'm doing wrong? I'm trying to reuse threads by having them just sit in an idle state until they get a signal. I also want my main() to wait for the threads to go back into their idle state before continuing. NUM_THREADS is 4, job_lock is a pthread_mutex_t, can_work and jobs_done are pthread_cond_t, jobs_completed is a bool and jobs_complete is an int. C++ code:
C++ code:
Acer Pilot fucked around with this message at 08:19 on Mar 28, 2013 |
# ? Mar 28, 2013 08:16 |
|
KNITS MY FEEDS posted:Can someone explain what I'm doing wrong? I'm trying to reuse threads by having them just sit in an idle state until they get a signal. I don't really feel like explaining how to do condition variables right and all the insane and wrong things you're doing, so I'm going to say this. Make a socketpair for each job thread and use that to talk to your threads.
|
# ? Mar 28, 2013 08:35 |
|
KNITS MY FEEDS posted:Can someone explain what I'm doing wrong? I'm trying to reuse threads by having them just sit in an idle state until they get a signal. You should either use an existing threadpool implementation like http://threadpool.sourceforge.net/ or resign yourself to spending a lot of time learning and debugging.
|
# ? Mar 28, 2013 09:12 |
|
Agh, thanks guys. I'll look into socketpairs or maybe use a thread pool instead.
|
# ? Mar 28, 2013 09:26 |
|
Alternately, just start by figuring out how a blocking queue works, move on to the other stuff once you've mastered that.
|
# ? Mar 28, 2013 09:35 |
|
That Turkey Story posted:The big pluses are the ability to directly specify whether or not a given function can throw an exception based on a compile-time constant (often based on whether or not another expression can throw), and that a noexcept does not need to unwind the stack. The latter makes it possible for callers of noexcept functions to be more optimal than callers of throw() functions in a compliant compiler. This seems really complicated to get right, I think I am going to jump ship into the -fno-rtti -fno-exceptions camp.
|
# ? Mar 28, 2013 12:38 |
|
Vanadium posted:This seems really complicated to get right, I think I am going to jump ship into the -fno-rtti -fno-exceptions camp. Writing exception-safe code is tough, but just keep in mind that turning exceptions off does not absolve you from dealing with exceptional cases. It may seem complicated, but it generally isn't as complicated as manually handling exceptional cases and propagating errors. Proper use of noexcept is also usually pretty simple unless you are dealing with very general templates and really want the function to be noexcept whenever it can be. In those cases, I personally just use a macro that automatically creates the clause (there is also an effort to have some kind of an automatic deduction facility in the next standard).
|
# ? Mar 28, 2013 18:13 |
|
So let's say I have a classcode:
code:
|
# ? Mar 28, 2013 19:30 |
|
|
# ? Jun 8, 2024 08:13 |
|
That Turkey Story posted:Writing exception-safe code is tough, but just keep in mind that turning exceptions off does not absolve you from dealing with exceptional cases. It may seem complicated, but it generally isn't as complicated as manually handling exceptional cases and propagating errors. Proper use of noexcept is also usually pretty simple unless you are dealing with very general templates and really want the function to be noexcept whenever it can be. In those cases, I personally just use a macro that automatically creates the clause (there is also an effort to have some kind of an automatic deduction facility in the next standard). http://akrzemi1.wordpress.com/2011/06/10/using-noexcept/
|
# ? Mar 28, 2013 19:33 |