|
Avenging Dentist posted:Yes of course. Because it's not passing the same pointer around.
|
# ? Jan 27, 2010 21:50 |
|
|
# ? Jun 10, 2024 05:22 |
|
At the point where the Der pointer was converted to a Base pointer, it was changed to point to the Base subobject. That is why dynamic_cast had to be magic to get the original pointer back.
|
# ? Jan 27, 2010 22:39 |
|
Ah, I get it. Thanks.
|
# ? Jan 27, 2010 22:48 |
|
Mustach posted:This is why static_cast works for them. dynamic_cast is necessary for downcasts (base to derived) and sidecasts (e.g. across an inheritance diamond). static_cast is fine for downcasts given that you know that your object is an instance of what you are casting to (or derived from that type) and is often preferable. You also can't use dynamic_cast unless the type you are casting from is polymorphic (it needs at least one virtual function). You should generally default to using static_cast for both up and down casts when you can and use dynamic_cast only when you have to. Times you have to use dynamic_cast are sideways casts or when a child inherits virtually or if you don't know if the cast can succeed.
|
# ? Jan 28, 2010 00:31 |
|
That Turkey Story posted:You should get on AIM/IRC. I have ideas for a C++ killer.
|
# ? Jan 28, 2010 02:27 |
|
I don't use AIM anymore. AIM is lame.
|
# ? Jan 28, 2010 04:05 |
|
Also, if you wanna be cool, you can use my new fangled C++0x multi_cast! http://www.codepaste.net/iqzbiz code:
|
# ? Jan 28, 2010 07:01 |
|
Ok so I'm chewing my way through Elements of Programming, I'm glad I bought it, and I feel like I understand much better what generic programming is about. What the book doesn't explain is why C++ is the language of choice for this. Now I'm not tremendously experienced with either C++ or any of its competitors, so I'm not looking to start an argument, just a "here is something C++ can do which no other language can do" (or maybe "here is something C++ can do which no other language with comparable development tools and libraries can do"). Is the multi-cast just posted an example? Is the STL an important part of the answer?
|
# ? Jan 28, 2010 07:49 |
|
GrumpyDoctor posted:What the book doesn't explain is why C++ is the language of choice for this. No other language has the necessary features to do generic programming in a sensible manner. Among the features required are templates (generics don't quite get all the way, but that of course depends on the implementation) and the decoupling of value/reference semantics from types (i.e. there are no "reference types" in C++, at least not in the sense that Java/C# have them). GrumpyDoctor posted:Is the STL an important part of the answer? No, but the STL is an example of what you can do with generic programming (though it's full of bad stuff too, in an effort to appease the standards body).
|
# ? Jan 28, 2010 08:29 |
|
GrumpyDoctor posted:Ok so I'm chewing my way through Elements of Programming, I'm glad I bought it, and I feel like I understand much better what generic programming is about. If you are looking for a practical code example apart from just theory, yes, STL is a good example, and even more-so, the Boost Graph Library. There are other languages suitable for generic programming, I.E. Haskell is often the one mentioned, though C++ still does have some advantages there too and vice-versa. If I had to narrow it down to a few important reasons that C++ is so much better suited for generic programming than languages like C# and Java, it's in its ability to represent associated types, to use types in functions at compile-time (in C++ via template metafunctions), to overload functions and to use type information to pick overloads/specializations of functions and types at compile-time. Along with this, you need the ability to separate generic algorithms from types and their intrinsic operations. Without these fundamentals you cannot create libraries like the STL or the Boost Graph Library or fully express pretty much any generic library (in the Stepanov sense of Generic Programming). You can't, for instance, write a generic algorithm in Java that operates on any forward range and automatically dispatches to specialized versions based on further concept information (I.E., what further concepts are modeled by the range). As an example, in C++ there is binary_search which has (at minimum) two different implementations -- one for forward ranges and another for random access ranges. Which algorithm is used is picked up automatically based on what category of iterators you pass in. This binary search is completely separate from operands it works on, in other words there is not a handwritten implementation for arrays or vectors or lists or deques. Further, none of those types or their associated iterator types have to inherit from a common base in order to be usable with the algorithm. If you choose to make your own container type, or if you have an already-made container from another library, you can use the algorithm without having to make a special definition for your type. In fact, you don't even have to modify your type! You can be using some pre-compiled C library that you can't change which has no knowledge of std::binary_search and yet still be able to use its containers with binary_search. All thats needed is a one-time specification of glue code (done usually with type traits and argument dependent lookup). No changes have to be made to the container itself, unless of course it simply isn't capable of the equivalent of basic iterator operations. Still, taking it a step beyond that, if you really wanted to, you could write a special definition for the algorithm with respect to your types if you can make one even more optimized (or at an even higher level, with respect to further concept refinements as is done often with segmented iterators, allowing a generic specialization). Any special version you write is automatically picked based on type data. Users of your types and of the algorithms need to know nothing about these implementation details, all they do is call binary_search and pass in their data. The compiler figures out exactly the dispatching and at absolutely no runtime cost. You can just as easily call binary_search with std::list iterators as you do std::vector iterators yet you get two very different implementations underneath, and remarkably, neither of those underlying algorithms were written directly for std::list or std::vector, they are entirely generic and are picked based on what concepts the operands to the algorithm model. There is no directly link between algorithms and types, they are done through the level of abstraction known as "concepts". The above is all extremely important. It means that any code you write, particularly if you are writing even higher-level generic algorithms that work with other generic algorithms internally, automatically takes advantage of these specializations implicitly. No matter how high of a level of abstraction you get, your algorithms are dispatched accordingly in the most specialized way possible at every single level. For instance if A calls B which calls C which calls D and E, when calling A, specialized versions of B, C, D, and E are all picked automatically. This is all done without the user ever having to know anything about implementation details and yet they still get as efficient code as if they had handwritten the algorithm for their type (unless of course there is a special implementation for that type or a concept it models, in which case they can write a special version which is again picked up automatically by anyone using that code). As was mentioned, STL is a good example of this, but the Boost Graph Library even more-so. With it you can take any graph implementation whether it is a datastructure you wrote, an ad-hoc implementation in your code, a graph from some premade library, or one of the graph implementations provided by the Boost Graph Library itself, and be able to use any of them with the BGL's algorithms. All it takes is minimum, 1-time glue code that you can write in a way that is non-intrusive to both your graph code and to BGL code.
|
# ? Jan 28, 2010 09:08 |
|
Avenging Dentist posted:No other language has the necessary features to do generic programming in a sensible manner. That Turkey Story posted:There are other languages suitable for generic programming, I.E. Haskell is often the one mentioned, though C++ still does have some advantages there too and vice-versa. Both of you were very helpful, but these parts seem to contradict each other...?
|
# ? Jan 28, 2010 20:53 |
|
GrumpyDoctor posted:Both of you were very helpful, but these parts seem to contradict each other...? Haskell can do the generic part just fine, but if you want to actually produce something the "programming" aspect becomes tricky. Fortunately, you can just embed a real language in a monad and get actual work done that way. Edit: More seriously, C++ is far and away the best mainstream language for generic programming. There are more than a few "fringe" languages like Haskell which can do many of the same things. For example, in Haskell you mostly accomplish generic programming through typeclassing, which is a very small and simple-to-understand type system extension with very predictable effects, whereas in C++ the template system is very much evolved to solve many different problems as well as generic programming, and as a result is harder to completely understand and debug. That said, Haskell is very much a toy language compared to C++; Haskell's module system is clearly not suited for large projects, it is difficult-to-impossible to add functionality to existing typeclasses, there's only the most primitive form of scope protection, etc. ShoulderDaemon fucked around with this message at 21:22 on Jan 28, 2010 |
# ? Jan 28, 2010 21:09 |
|
GrumpyDoctor posted:Both of you were very helpful, but these parts seem to contradict each other...? Any contradiction should have been cleared up by the rest of our posts. "Sensible manner" is a subjective phrase and I think I was pretty clear in the objective qualities that make Generic Programming feasible in C++. Out of most statically-typed mainstream languages (particularly C#, C++, Java, C), C++ is the only one you can do Generic Programming in in the sense that Stepanov describes it, unless you consider Haskell mainstream, though again, neither of these languages is really ideal. Of all the features I describe as being fundamental to Generic Programming, look at the subset of languages that support them all and you will get the languages that let you do Generic Programming to the extent that C++ can (most languages fall way behind). If that isn't clear, read this (old but still relevant) which has a much more detailed table of features that aid in Generic Programming and has direct comparisons between some languages along with an attempt to implement a generic graph library in those languages. This paper is good as well.
|
# ? Jan 28, 2010 21:30 |
|
More to the point, I don't know Haskell.
|
# ? Jan 28, 2010 22:53 |
|
Thanks for those papers. Have any of you ever looked into D for generic programming? I would love an excuse to learn/use D. comparison of D and C++ templates (C++0x included) D template constraints
|
# ? Jan 29, 2010 00:18 |
|
GrumpyDoctor posted:Thanks for those papers. Have any of you ever looked into D for generic programming? I would love an excuse to learn/use D. That syntax looks really bad, honestly. Also their comparison is crazily inaccurate, since it seems to be more "can you type pretty much the same thing and have it work in C++ or D?" rather than "does this feature exist in C++ and D?" For instance, they mention compile-time execution of functions and then claim that C++ can't do it, but it can, by way of metafunctions. Additionally, the constraints look like a not-very-good version of the ill-fated C++0x concepts, which themselves had a lot of problems. One of the fundamental issues here is that creating a good generic programming language means (in my opinion) divorcing yourself from the mistakes that C and C++ made. D sorta tries to do this with respect to C++ only, but they don't go far enough, and in some areas, they don't improve at all. For instance, the "static if" syntax is boneheaded, since the compiler should know when you're dealing with a value known at compile time and just do it automatically.
|
# ? Jan 29, 2010 00:35 |
|
The only thing that D has that I wish C++ had is invariant.
|
# ? Jan 29, 2010 02:11 |
|
Mustach posted:The only thing that D has that I wish C++ had is invariant. A module system? Explicit scope guards? Decidable grammar?
|
# ? Jan 29, 2010 17:12 |
|
Modules would be really cool, but I don't yearn for them too frequently. Scope guards are provided nicely by Boost, so I don't need a keyword. And if the grammar got nicer, it just wouldn't be C++.
|
# ? Jan 29, 2010 17:24 |
|
GrumpyDoctor posted:D template constraints D's template constraints are not terrible, but in practice they are no better than using enable_if in C++ since they only serve as a way to rule out overloads. All they've done is translated a library feature of C++ into a language feature. While this makes the syntax look cleaner in some sense, it doesn't provide any additional functionality. If you want truly effective constraints, you need a system that picks overloads based on what concepts the arguments model and prefers more refined concepts over less. Right now the only way you can somewhat simulate that is with tag dispatch.
|
# ? Jan 29, 2010 21:10 |
|
Not sure where else to put this, I suppose I could make a new thread but I'll try here first. I want to have two "sets" of iptables rules for a Linux kernel. One that can be modified by the administrator of the machine (like it currently is) and one that can only be modified by the kernel. I figured it wouldn't be too much of a pain to simply include the client code for iptables (so I don't have to recode all the parsing work) into the kernel, and duplicate all the target internal netfilter data structures to only work with the kernel version of iptables. I doubt there's an easy way to handle the conflicting includes (without knowing a lot about the structure of the kernel). Is anyone familiar enough with netfilter to provide an alternative approach? I considered writing everything from scratch, but was hoping to save time reusing code. EDIT: I guess to clarify: I want a kernel-space interface to the iptables rules in the kernel. This interface should create rules that can ONLY be removed by the kernel-space interface. defmacro fucked around with this message at 21:32 on Jan 29, 2010 |
# ? Jan 29, 2010 21:10 |
|
Is there a way using macro trickery or something similar to convert an enum value into a string representing that value? e.g. say I have an enum defined as code:
code:
|
# ? Jan 30, 2010 12:43 |
|
beuges posted:Is there a way using macro trickery or something similar to convert an enum value into a string representing that value? Yep. #define PRINT_MY_ENUM(myEnum) printf(#myEnum) void printSomeEnums() { PRINT_MY_ENUM(SomeEnum); }
|
# ? Jan 30, 2010 14:13 |
|
beuges posted:Is there a way using macro trickery or something similar to convert an enum value into a string representing that value? code:
|
# ? Jan 30, 2010 14:21 |
|
Vinterstum posted:Yep. Mustach fucked around with this message at 15:08 on Jan 30, 2010 |
# ? Jan 30, 2010 15:05 |
|
Brecht posted:
Sorry, to be more clear, I want it to print out "Commands::UpdateContactInfo" or just "UpdateContactInfo" instead of "5"
|
# ? Jan 30, 2010 15:25 |
|
I wrote something to do this as a pet project with Boost::preprocessor, but you had to use a macro and some wonky syntax to declare the enum as well. Despite making something that worked, I never really considered it actually worth using.
|
# ? Jan 30, 2010 16:10 |
|
beuges posted:Is there a way using macro trickery or something similar to convert an enum value into a string representing that value? Not a macro, but make an array of strings, in the same order: code:
code:
StackOverflow has some other suggestions. mr_jim fucked around with this message at 16:32 on Jan 30, 2010 |
# ? Jan 30, 2010 16:29 |
|
beuges posted:Sorry, to be more clear, I want it to print out "Commands::UpdateContactInfo" or just "UpdateContactInfo" instead of "5" code:
|
# ? Jan 30, 2010 16:48 |
|
Aha... that's too much effort then - I just wanted something quick to use for debug logging, but creating a map or array (the array idea won't even work because not all the enum's I want to log about are sequential) is going to be too much of a bother. Guess I'll have to look up the numbers against the enum declarations as they come up.
|
# ? Jan 30, 2010 16:57 |
|
Declare your enum using a construction like this, in some header:code:
Now the implementation of Foo_to_string is: code:
|
# ? Jan 30, 2010 19:43 |
|
ctz posted:Declare your enum using a construction like this, in some header:
|
# ? Jan 30, 2010 20:28 |
|
Hey guys, I'm somewhat new to programming but I've been trying to make a program that creates fractals. I've been able to make fractals with the color of a point outside the fracal related to the number of iterations it take to exceed the radius. For example this code...code:
I've looked at http://www.codeproject.com/KB/cs/Mandelbrot_set.aspx http://linas.org/art-gallery/escape/smooth.html etc but I can't produce a smooth exterior color gradient. So the question is how do I fill in the missing part of the code vvvvhere code:
|
# ? Jan 30, 2010 21:14 |
|
Brecht posted:Then an enum is not what you want. Quit being stupid. 1) People have already posted solutions that work (albeit a bit messily), 2) he's already said this is just for debugging, which is a totally legit reason to do something like this.
|
# ? Jan 30, 2010 21:33 |
|
Fedaykin posted:So the question is how do I fill in the missing part of the code What are you confused about? You get the fractional escape count (you did that) and then map it to a color.
|
# ? Jan 30, 2010 21:41 |
|
Mustach posted:Are you being snarky or do you just not know how macros work? Because that doesn't work for his given use case; it'll just print "command". I was responding to the "Is there a way using macro trickery or something similar to convert an enum value into a string representing that value" part (you know, the bit I quoted), since it seemed the OP's main issue was that he didn't know about the # trick.
|
# ? Jan 30, 2010 21:44 |
|
Avenging Dentist posted:What are you confused about? You get the fractional escape count (you did that) and then map it to a color. http://linas.org/art-gallery/escape/smooth.html I don't want the 'bands' created by using the iteration integer.
|
# ? Jan 30, 2010 21:51 |
|
Fedaykin posted:http://linas.org/art-gallery/escape/smooth.html I don't want the 'bands' created by using the iteration integer. That doesn't explain what you're confused about? Your escape count in the second sample isn't an integer.
|
# ? Jan 30, 2010 22:08 |
|
Avenging Dentist posted:That doesn't explain what you're confused about? Your escape count in the second sample isn't an integer. ok, then my question is how do you apply that number and turn it into rgb?
|
# ? Jan 30, 2010 22:12 |
|
|
# ? Jun 10, 2024 05:22 |
|
Fedaykin posted:ok, then my question is how do you apply that number and turn it into rgb? From your link: http://www.codeproject.com/KB/cs/Mandelbrot_set.aspx#premain1 (not how I'd do it)
|
# ? Jan 30, 2010 22:14 |