| Catfish3 (279) | |||
|
I'm planning to add this to the Source Code section, especially because the Caesar cipher seems popular as a homework. I tried to write high quality, bare C++11 code. Now is the time to shoot it down. Be ruthless!
| |||
|
Last edited on
|
|||
| Catfish3 (279) | |
|
Semi-shameless bump, after moving here from Generic. It may have been better to post this in my Source Code thread, but I thought, why ruin whatever it derailed into? If you see any bugs, or have ideas for a better way to do this, let me know. Thanks. | |
|
|
|
| cire (2354) | |
| Might make ab static in caesar_cipher, but it looks good to me. | |
|
|
|
| chrisname (6191) | |||
Nothing but this: Why not pass argv[0] to print_usage so that it can use that instead of "program.exe"? I usually do it like this:
| |||
|
|
|||
| Catfish3 (279) | |||
Could you please explain what the benefit would be, in doing that?
Because argc could be 0, and argv[0] could be NULL. Otherwise that's how I would've done it, too. | |||
|
|
|||
| cire (2354) | |||||
The string would only be constructed once per program instance instead of once per function invocation. Since this program doesn't invoke the function more than once (outside of the debug driver,) it doesn't make any practical difference. | |||||
|
Last edited on
|
|||||
| ResidentBiscuit (2650) | ||
Wouldn't argc always be at least 1 on successful entrance? | ||
|
|
||
| cire (2354) | ||
For reference, 3.6.1.2 says:
| ||
|
|
||
| Catfish3 (279) | ||
Not necessarily. If you're on Linux, check out the exec() functions. You should be able to pass zero arguments while successfully http://linux.die.net/man/3/exec | ||
|
Last edited on
|
||
| chrisname (6191) | |
| On a strictly compliant POSIX implementation (POSIXLY_CORRECT=1 for GNU), argc is guaranteed to be >= 1. On any other system, argc can be any positive integer. | |
|
|
|
| Luc Lieber (985) | |
@ line 48, why aren't you capturing the two variables as references in your lambda? It doesn't appear to me that you're mutating either of them within your lambda expression.[&ab, &rot_ab](char c) -> charalternatively, [&](char c) -> charto capture them by reference implicitly. Shaving off the microseconds, we are. Now I'm just nitpicking, but you could add a bit of documentation for what happens if a shift larger than the alphabet size is provided. If I was simply given the function header and that documentation, I'd expect the function to puke if I passed in 100,000,000 and as such, I'd be truncating the shifts in my own user code before passing them. | |
|
Last edited on
|
|
| Catfish3 (279) | ||||
Not knowing of a way to capture by constant reference, I reached the conclusion that capturing by reference, just to avoid copying two 26 character std::strings, would be a misuse of the feature.
Thanks, I'll do that soon.
I thought that since I didn't document any constraints for the shift value, the user should assume that the function works for any value. Which it does. But I understand where you're coming from. | ||||
|
|
||||
| Luc Lieber (985) | |||
I hadn't thought of capture by const-reference until you mentioned that...it seems very odd that the standards committee overlooked that. I read through the draft papers again to make sure that I didn't miss it, but it's definitely not there. I guess I still don't see how a reference capture would be considered misusing a feature in this case. At any rate, const-reference capture should definitely be added to the standard unless there's a damn good reason not to. | |||
|
|
|||
| hamsterman (4435) | |||
| |||
|
|
|||
| Catfish3 (279) | ||||
I am interested in sample code illustrating a more intuitive approach.
Honestly, I never touched Unicode, but I feel it has no place in this program. However, if UTF-8 encodes using eight bits, so I could add support for it while keeping only one version. Have you any comments in that regard? I don't think the functions from cctype will be usable anymore?
Here I disagree. If one is comfortable with std::transform(), it should be easier to understand than a for() loop iterating two ranges at the same time. Again, post sample code so that I see better what you mean. | ||||
|
Last edited on
|
||||
| hamsterman (4435) | |||||
The more "intuitive" approach is
The thing to notice is that rot_ab.at(ab.find(c)) turned into (c -'a' + shift)%26 + 'a' and that a third of the code is gone.Note, I'm not trying to encourage ASCII arithmetic. My point (one third of it) is that you wrote a more general piece of code and then restricted it to what I wrote above. As for the in memory rotation, it looks odd (to precompute a trivial computation) but I can't find a real reason why that would be bad, so I guess it isn't... As for Unicode, I don't really know how C++ deals with it. It seems that external libraries are used for that. In general you shouldn't say that Unicode has no place in text manipulation program though. You may be from UK or US, but not everybody else is. Also, you have some misconceptions about Unicode encodings. I suggest you read http://en.wikipedia.org/wiki/UTF-8#Description As for "transform", compare
Also, I suppose more people are comfortable with "for" than with "transform". Finally, I'll add that if you moved the rotation of one character into another (properly separated) function (lambda is fine as C++ function passing is such a pain), I'd be very much for using "transform". The problem is when you take things intended to make code clean or concise and achieve neither. | |||||
|
|
|||||
| Catfish3 (279) | ||||
The D programming language has a global ASCII alphabet string. If C++ had something similar, and I used it instead of handcrafting ab, would you have made the same observation?
Neither am I. Then could you rewrite your function so that it doesn't rely on it?
This again revolves around ASCII arithmetic, doesn't it? At some point I even thought about using an std::map<char, char>. But that doesn't actually simplify anything. | ||||
|
|
||||
| devonrevenge (897) | |
| i wish i knew how to install c++11, then i could run it :/ happy xmas | |
|
|
|
| hamsterman (4435) | |
|
quote 1. Yes, I would. quote 2. I'm not criticizing use of an alphabet string. I'm criticizing use of an alphabet that is hard coded to match with ASCII characters. ASCII arithmetic is bad not because it is somehow unsafe, but because it's ASCII (and hard to change) (and a bit unreadable). quote 3. No, this bit is about syntax only. I guess moving the lambda into its own variable would be a step forward. By the way, have you considered doing binary search on the alphabet? Linear is kind of odd (even though you'd only gain a few compares with binary). I think it's okay to ask for it to be sorted. | |
|
|
|
| Catfish3 (279) | ||||
As opposed to matching with what?
I do not understand what you mean. Could you give an example, please?
That's an interesting idea, but I think it's overkill. The real bottleneck ought to be the stream iterators, which read and write byte by byte (I think). And even that is irrelevant for the small text files this program is supposed to be used on. | ||||
|
Last edited on
|
||||