Analysis of C ++ templates (medium)

zhaozj2021-02-11  222

The type in the function template is summarized

A very simple but useful example:

/ /: arraysize.h

// Uses template Type Induction To

// discover the size of an arch

#ifndef arraysize_h

#define arraysize_h

Template

INT ASZ (T (&) [Size]) {Return Size;}

#ENDIF // Arraysize_H ///: ~

No sizeof () is used, but you can point out the size of the array in the compile stage, you can have more concise methods to calculate the size of the compile time array.

//: c03: arraysize.cpp

// the return value of the template function

// ASZ () is a compile-time constant

#include "../Arraysize.h"

int main ()

{

INT A [12], B [20];

Const int SZ1 = ASZ (a);

Const int SZ2 = ASZ (b);

INT C [SZ1], D [SZ2];

} ///: ~

Of course, the premise of the normal operation of the program is that the array has given a size when defined.

Obtain an address of an instantiated function template

There are many places, you need to get the function entry address, for example, you may have a function, its parameter is a pointer to another function, of course, this referred to the function may be generated from a template, Therefore, you need a way to get this function address.

//: C03: TemplateFunctionAddress.cpp

// taking the address of a function generated

// from a template.

Template Void F (t *) {}

Void h (void (* pf) (int *)) {}

Template

Void G (Void (* PF) (T *)) {}

int main ()

{

// Full Type Exposition:

H (& f );

// Type Induction:

H (& f);

// Full Type Exposition:

G (& f );

// Type Inductions:

G (& f );

G (& f);

} ///: ~

This example tells a lot of different topics. First, even if you use the template, the type must match the - function h () takes a pointing function pointer, this correspondence accepts the parameter of the int type Returns the VOID type. And this is the characteristics of F. Second, the function of the function pointer is used as a parameter itself can also be a template, just like G. In the main () function, you can see the type in summary is also working here. The first call h () explicitly gives the template parameter f, but it is seen from H () that it only processes the function pointer to function using the INT type variable, which may be summarized by the compiler. G () is also intentional, because there are two templates to use here. The compiler cannot summarize this type, and it will not do anything, but if F and G are integrated into int, other compilers will do it.

Member class in the template

Apply a function to the STL series

Suppose you want to use a STL series container and apply a function to all objects contained in the container, which is said to be because a vector can contain various types of objects, you need a function to work with the vector, process It contains the various objects: //: c03: ApplySequence.h

// Apply a Function to an STL Sequence Container

// 0 Arguments, Any Type of Return Value:

Template

Void Apply (SEQ & SQ, R (T :: * f) ())

{

TypeName SEQ :: item IT = Sq.begin ();

While (it! = sq.end ())

{

((* IT) -> * f) ();

IT ;

}

}

// A parameter, the return value is uncertain

Template

Void Apply (SEQ & SQ, R (T :: * f) (a), A a)

{

TypeName SEQ :: item IT = Sq.begin ();

While (it! = sq.end ())

{

((* IT) -> * f) (a);

IT ;

}

}

// Two parameters, return value

Template

Class A1, CLASS A2>

Void Apply (SEQ & SQ, R (T :: * f) (A1, A2),

A1 A1, A2 A2)

{

TypeName SEQ :: item IT = Sq.begin ();

While (it! = sq.end ())

{

((* IT) -> * f) (A1, A2);

IT ;

}

}

// So, the most similar parameters are passed ///: ~

Apply () Function Template uses a reference to the container class and a member pointer for a container class internal member function. It uses an Iterator to move to the STACK to use this function to each object.

Note that there is no STL's header file contains in ApplySequence.h, so it is not limited when used in common use with the STL series. Of course, when using, taking into account the specificity of Iterator, we can only apply it to the STL series (don't forget, we must use items).

You can see, there is more than one apply (), so it can overload the function template, each version uses a different number of parameters because it is a template, these parameters can be any type, the only limit is : This is not a super template to create a new template for you.

Test our different versions of Apply ().

//: c03: Gromit.h

// the techno-dog. HAS Member functions

// with various numbers of arguments.

#include

Class Gromit

{

Int Arf;

PUBLIC:

GROTI (int Arf = 1): Arf (Arf 1) {}

Void Speak (int)

{

For (int i = 0; i

Std :: Cout << "Arf!";

Std :: cout << std :: endl;

}

Char Eat (float) {

Std :: cout << "chomp!" << std :: endl;

Return 'Z';

}

Int Sleep (Char, Double)

{

Std :: cout << "zzz ..." << std :: endl;

Return 0;

}

Void sit (void) {}

}; ///: ~

Now, the function appl () can use the vector to use to make a container, call the member function and the object being included:

//: c03: ApplyGromit.cpp

// test applysequence.h

#include "fund.h"

#include "applysequence.h"

#include

#include

Using namespace std;

int main ()

{

Vector DOGS;

For (int i = 0; i <5; i )

Dogs.push_back (New Gromit (i));

Apply (Dogs, & Gromit :: Speak, 1);

Apply (Dogs, & Gromit :: Eat, 2.0F);

Apply (DOGS, & GROMIT :: Sleep, 'Z', 3.0);

Apply (Dogs, & Gromit :: Sit);

} ///: ~

Although Apply definition is somewhat complicated, novice may not be fully understood, but its use is simple and clear, novice also knows how to use it, I think this is the goal of struggling for your own procedure: No need to know the details, Just know that you can achieve your goals.

Template template

//: C03: TemplateTemplate.cpp

#include

#include

#include

Using namespace std;

// as long as things are simple,

// this approach works fine:

Template

Void Print1 (C & C)

{

TypeName C :: Iterator IT;

For (it = c.begin (); it! = c.end (); it )

COUT << * IT << "

Cout << Endl;

}

// Template-Template Argument MUST

// be a class; canNot USE TypeName:

Template Class C>

Void Print2 (C & C)

{

Copy (C. Segin (), C.End (),

Ostream_iterator (cout, "));

Cout << Endl;

}

int main ()

{

Vector V (5, "YOW!");

Print1 (V);

Print2 (V);

} ///: ~

Member function template

In fact, we can also use Apply () as a member function template in a class, which makes the declaration clearer: DOGS.Apply (& Gromit :: Sit);

As a member in the container class, the definition of Apply () is proven to be very clear. In order to complete this, we need to inherit a new container from the existing STL series container, add our new function to this container. Of course, in order to have the best adaptability, we will use the STL series container, and must use the template of the template to do this, tell the compiler that a template parameter is a template, and itself acts as a type. The parameters can also be initialized. look down:

//: c03: applymember.h

// applysequence.h modified to use

// MEMBER FUNCTION TEMPLATES

Template Class SEQ>

Class SequenceWithapply: Public SEQ

{

PUBLIC:

// 0 Arguments, Any Type of Return Value:

Template

Void Apply (R (t :: * f) ())

{

Iterator it = begin ();

While (it! = end ())

{

((* IT) -> * f) ();

IT ;

}

}

// 1 Argument, Any Type of Return Value:

Template

Void Apply (r (t :: * f) (a), a a)

{

Iterator it = begin ();

While (it! = end ())

{

((* IT) -> * f) (a);

IT ;

}

}

// 2 Arguments, Any Type of Return Value:

Template

Void Apply (R (t :: * f) (A1, A2),

A1 A1, A2 A2)

{

Iterator it = begin ();

While (it! = end ())

{

((* IT) -> * f) (A1, A2);

IT ;

}

}

}; ///: ~

Because they are members of the class, the Apply () function does not need so many parameters, and the class of Iterator is not required to be specified. Of course, Begin () and end () are also a member of the new class, all of which looks so clear, clear. However, the basic code is still the same.

//: c03: applygromit2.cpp

// Test Applymember.h

#include "fund.h"

#include "applymember.h"

#include

#include

Using namespace std;

int main ()

{

Sequence, Vector> DOGS;

For (int i = 0; i <5; i )

Dogs.push_back (New Gromit (i));

Dogs.Apply (& Gromit :: Speak, 1);

DOGS.Apply (& Gromit :: Eat, 2.0F);

Dogs.Apply (& Gromit :: Sleep, 'Z', 3.0); DOGS.Apply (& Gromit :: Sit);

} ///: ~

From the concept: you are from now

Dogs

Call in this container

Apply ()

This method is.

转载请注明原文地址:https://www.9cbs.com/read-4358.html

New Post(0)