Wild programming: type string (Typelists) and app Andrei AlexandRescu
It's hard to say how this started. I personally only say: Start me in the USENET newsgroup comp.lang.c . Moderated (by way of advice) See some posts, there is a weird template recursive. Later, when it encountered huge difficulties in the realization of the ABSTRACT FACTORY, some structure appeared in my mind. Others have also been independent of similar work because various types of strings are everywhere. Czarnecki and Eisnecker have introduced a type string that actually contains constant integer values in [1]. The MPL library also defines a type string, and there are some algorithms for operation type strings. Modem C Design also introduces a simple type string implementation and uses it in at least five generic components (Functor, Visitor, AbstractFactory, StaticDispatcher, Tuple), is not two automatic class hierarchics (GenScatterHierarchy and GenlineArchy) ). The applicability of the type string is now certified. Know that type skewers will definitely improve your technology and help you better understand the current C libraries now. This article has again introduced the type string and fun program that can solve practical problems. You can't ask the type string as a Christmas husband asked it to Christmas gifts, but if you absorb any new knowledge of C like a block sponge, you can still find a lot of interesting things, so, continue to read. So what is a type string? Is the type string is also a strange strange template monster? In fact, type strings are too simple, nothing, C community does not use the type string so much unhealried. Template
TypeDef Typelist
You can do this because the type string is a type so that it can be used as a type of a large type string. According to conventions, a type string can only appear in another tail position of another type, and cannot be a head position; thus makes the operation of the type string easier, but does not reduce flexibility. We almost have to complete, we only need to define an auxiliary type, this auxiliary type as the end flag of the type string (similar to the NIL of Lisp). We call it null_typelist:
Class null_typelist {};
The correct style of the type string of this saving floating point type is:
TypeDef Typelist
Line-shaped generation type string: three ways do not need to see any good eyes, as long as several members, the established type strings will become very ugly. All of these: Nested template instances, in order to avoid and >> Operators confused in adjacent> must be split, it makes the type string too difficult to use several methods for processing this problem, Loki [3] uses macro definitions The definition is as follows:
#define Typelist_1 (T1) TYPELIST (T1, Null_Typelist> #define Typelist_2 (T1, T2) Typelist
Just like you can see, each macro definition relies on one. Loki defines the "constructor" of the type string with up to 50 members. More than 50, you either define a new macro definition, either manually connect the type string. I should know that the use of macro is not a good solution. Text conversion is very powerful, but the C preprocessor is too simple. When you think you have used it, it will always bite you behind it. In this example, the problem is that you cannot use these macros to be used with touchpads, even the simplest touchpad. for example:
TypedEf Typelist_2 (Vector
The preprocessor can handle parentheses, but cannot handle angle
Template
Template
Template
Template
The above example supports up to four types, you can use cons:
TypeDef Cons
The CONS template is based on partial specilization. When you instantiate CONS
Template
Template
Template
Template
Now if you define a macro:
#define Typelist (a) cons
TypeDef Typelist (Float, Double, Long Double) FLOATING_POINT_TYPE;
If you can succeed, people believe that two pairs of parentheses are so beautiful, this is really good. Ok, I know that I need to explain it. The first thing, void (*) (t1) is a C type (I have no misplaced words!): A function pointer accepts a parameter of T1, returns Void. This type is more familiar with VOID (* FUN) (T1), which actually contains a structure of the name. The CONS Template class is used to receive a function pointer for one, two, three or four parameters to pick up. Then Typelist macro opens this structure: Typelist (Float, Double, long double) becomes cons
Improved (Ad-Hoc Visitation) Visitor Design Pattern provides a clear solution for complex issues. But its defect limits its application. Essentially, the visitor mode provides you with a safe way to increase the operation of the class level, without modifying this class hierarchy itself, the price is: When the class level changes, you have to change all of these operations. To know the details, look at the famous "design model" [5] or specially speaking C "Modern C Design" [3]. A rarely mentioned and access-related issues is: You must support access modes in the class level. This support refers to an accept member function in this support. In other words, if you can't rewrite a class hierarchy that does not support access, you can't access it. If you do not support access, and if you want to add an action in the class level, you don't rewrite it. Then you are destined to use the annoying Switch-ON-Type method. In the real world, it is very common: you use the base class in the old class library to increase your own inheritance class. Imagine, for example, there is a class level with documentItem as the root, real type to Textarea, VectorGraphics, and Bitmap. These are inherited directly from DocumentItem. In order to add actions SomeOperation, you can do this:
void SomeOperation (DocumentItem * p) {if (TextArea * pTextArea = dynamic_cast
Template
Template
template
Adhocvisitor accepts a type of string as its parameters and uses technologies similar to CONS. That is to say, Adhocvisitor has two partial specialization versions, a header of the processing type string and recursively handled the tail of the type string, and the other is to stop recursive. The first special version defines a pure virtual function Visit (h *), H is the header of the type string. In addition, AdhocVisitor inherits itself, is an AdhocVisito instantiated with this type of string. Essentially, AdhocVisitor
Let us see how this is working. The first line defines a type of string MyHierarchy contains Textarea, VectorGraphics, and Bitmap. Note that root DOCELEMENT is not part of the type string. The Concretevisitor class is directly defined in the main function - this is reflecting the name of the specific implementation "即 (Ad Hoc). As you guessed, Concretevisitor inherits and overloads the three pure virtual functions of AdhocVisitor
Analysis is as important as the details of the analysis and exploration code. The efficiency has to be recognized. Compare the clumsy IF / ELSE solution of the most in front, we still use Dynamic_cast, and we have made extra virtual function calls ( Visit). The virtual function call can be easily eliminated by the following steps: * Accept the second template parameter EFFector in AdhocVisitor, and inherited from it * Let AdhocVisitor assume that these Visitor functions are defined in the Effector and use them, rather than using them in AdhocVisitor. * (Optional) In each successful Dynamic_cast branch, the EFFECTOR :: Visage is guaranteed to have the correct form (return value and parameter list). By obtaining the address of the Effector :: Visit, it can be easily implemented when compiling. * Take Concretevisitor from main. Put Concretevisitor in the function. Concept, there is no error. However, 唉, C does not allow local types to be passed as template parameters. * Use the AdhocVisitor template to incorporate the type string and your Concretevisitor class as a template parameter, you can call StartVisitation to start access. Why not discuss this optimization from the beginning (instead of practicing it as a hateful practice to the reader)? This optimization solution requires some other very difficult questions, and this article only focuses on type string usage issues. Coupled all the scenarios need to have a class level information. But it is very important. You must notice the Switch-Type solution requires you to disperse the information of the class level into the code. Based on the type of string, let you concentrate this information, you only need to provide a TypedEf. , Then you only modify it when you modify the class level.
Maintenance Don't forget that our discussion is in a special environment: You can't add a function to the class level you want to modify. That is from the beginning, I have given us some defects. That is to say, it has brought very important maintenance based on the resolution of type strings. Suppose you forget to handle Bitmap types in your Concretevisitor class:
Struct Concretevisitor: adhocvisitor
This way the compiler will not let you instantiate Concretevisitor, because AdhocVisitor
Conclusion This article introduces a type string implemented with C , with a complete use example. The type string is strong and important, mostly because it can achieve a new common method (IDioms). This is a better solution for complex issues. Most importantly, the type string encourages you to reach by letting you extract the bored repetitive code.
Reference book [1] K. Czarnecki and U. Eisnecker. Generative Programming: Methods, Tools, And Applications (Addison-Wesley Longman, 2000). [2] See