Description about constraints that cannot be defined for template parameters

Source: Internet
Author: User

 

If a type error occurs, it may occur in complicated for_each () calls. For example, if the element type of the container is int, we will get a fuzzy error related to for_each () (because the shape: Draw method cannot be called for an int value)

Yes, and the method is very simple and common.

Look at this:

Template <class container>
Void draw_all (container & C)
{
For_each (C. Begin (), C. End (), mem_fun (& shape: Draw ));
}

If a type error occurs, it may occur in complicated for_each () calls. For example, if the element type of the container is int, we will get an error with fuzzy meanings related to for_each () (because we cannot call shape for an int value :: draw method ).

To capture this error in advance, I write as follows:

Template <class container>
Void draw_all (container & C)
{
Shape * P = C. Front (); // accept only containers of shape * s
For_each (C. Begin (), C. End (), mem_fun (& shape: Draw ));
}

For most compilers, initialization of the intermediate Variable P will trigger an easy-to-understand error. This tip is common in many languages and must be used in all standard creation. In the finished code, I may write the following code:

Template <class container>

Void draw_all (container & C)
{
Typedef typename container: value_type T;
Can_copy <t, shape *> (); // accept containers of only shape * s
For_each (C. Begin (), C. End (), mem_fun (& shape: Draw ));
}

This makes it clear that I am creating an assertion ). The can_copy template can be defined as follows:

Template <class T1, class T2> struct can_copy {
Static void constraints (T1 A, T2 B) {T2 c = A; B = ;}
Can_copy () {void (* p) (T1, T2) = constraints ;}
};

Can_copy (at runtime) checks whether T1 can be assigned to T2. Can_copy <t, shape *> checks whether T is of the shape * type, or a pointer to an object of the class inherited by the shape class, or a type that is converted to the shape * type by the user. Note that this definition is minimized:

The constraints to be checked for a row name and the type to be checked

One row lists the constraints to be checked (constraints () function)

One row provides the method to trigger the check (through the constructor)

Note that this definition has a reasonable nature:

You can express a constraint without declaring or copying variables. Therefore, the constraint writer does not need to imagine how variables are initialized and whether objects can be copied or destroyed, and so on. (Of course, exceptions occur when the constraints check these attributes .)

The current compiler does not need to generate code for the constraints.

Define and use constraints without using macros

When the constraint fails, the compiler will give an acceptable error message, including the word "constraints" (giving the user a clue), the name of the constraint, and detailed errors that cause constraints to fail (for example, "unable to use double * to initialize shape *").

In C ++, is there anything similar to can_copy -- or better? In the design and evolution of C ++ language, the difficulties in implementing this general constraint in C ++ are analyzed. Since then, many methods have emerged to make the constraint class easier to write, while still triggering good error messages. For example, I trust the function pointer I use in can_copy, which is derived from Alex Stepanov and Jeremy siek. I don't think can_copy () can be standardized-it requires more use. Similarly, in the C ++ community, different constraints are used. Which constraint template is the most effective in a wide range of applications, no consensus has been reached.

However, this approach is more common than the mechanism provided by the language specifically for constraints checks. In any case, when writing a template, we have the most abundant expressive power provided by C ++. Look at this:

Template <class T, Class B> struct derived_from {
Static void constraints (T * P) {B * pb = P ;}
Derived_from () {void (* p) (T *) = constraints ;}
};

Template <class T1, class T2> struct can_copy {
Static void constraints (T1 A, T2 B) {T2 c = A; B = ;}
Can_copy () {void (* p) (T1, T2) = constraints ;}
};

Template <class T1, class t2 = T1> struct can_compare {
Static void constraints (T1 A, T2 B) {A = B;! = B; A <B ;}
Can_compare () {void (* p) (T1, T2) = constraints ;}
};

Template <class T1, class T2, class T3 = T1> struct can_multiply {
Static void constraints (T1 A, T2 B, T3 c) {c = a * B ;}
Can_multiply () {void (* p) (T1, T2, T3) = constraints ;}
};

Struct B {};
Struct D: B {};
Struct DD: D {};
Struct x {};

Int main ()
{
Derived_from <D, B> ();
Derived_from <DD, B> ();
Derived_from <X, B> ();
Derived_from <int, B> ();
Derived_from <X, int> ();

Can_compare <int, float> ();
Can_compare <X, B> ();
Can_multiply <int, float> ();
Can_multiply <int, float, double> ();
Can_multiply <B, x> ();
Can_copy <D *, B *> ();
Can_copy <D, B *> ();
Can_copy <int, B *> ();
}

// Typical "elements must inherit from mybase *" constraints:

Template <class T> class container: derived_from <t, mybase> {

//...

};

In fact, derived_from does not check the source (derivation), but only checks the conversion, but this is often a better constraint. It is difficult to think of a good name for the constraint.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.