Introduction to C + + macros and templates

Source: Internet
Author: User
Tags processing instruction

Referring to the 14th chapter of 21-day learning and C + +, the macro and template in C + + is studied, and the main contents are summarized as follows:

(1) Introduction to Preprocessor

(2) Keyword # define and macro

(3) Introduction to the template

(4) How to write function templates and template classes

(5) The difference between a macro and a template

(6) Compile phase check using Static_assert

*************************************************************************************************************** *********************

1 preprocessor and compilers

Preprocessor: Run before the compiler, depending on the programmer's instructions, decide what to actually compile, and the precompiled directives begin with #

Typical applications include the following:

(1) Defining constants using # Define

Typically used when defining the length of an array. The constants that are defined are simply text replacements, not type detection, such as defining a # define PI 3.1416来, the type of the macro Pi compiler does not detect, and does not know whether it is a float or a double.

When defining constants, it is better to choose to use the keyword const and data type, such as const double PI = 3.1416, rather than using a macro to define it much better.

(2) Use a macro to avoid multiple inclusions

C + + is typically done by placing declarations of classes and functions in a header file (. h), and defining functions in a source file (. cpp), so that you need to include the header file in a. cpp file with # include

/*

#ifndef Header1_h_

#define Header1_h_

#include <header2.h>

....................................

....................................

....................................

#endif

Header2.h is similar to this, but the macro definition is different and contains Header1.h:

/*

#ifndef Header2_h_

#define Header2_h_

#include

....................................

....................................

....................................

#endif

Explanation: #ifndef是一个条件处理命令, let the preprocessor continue only if the identifier is undecided, #endif告诉预处理器, and the conditional processing instruction ends here. Therefore, after the preprocessor first processes Header1.h and encounters #ifndef, it discovers that Header1_h_ has not yet been defined and continues processing.#ifndef后面的第一行定义了宏Header1_h_, make sure that when the preprocessor processes the file again, it ends when the first line that contains the #ifndef is encountered, because the condition in it becomes false. Header2.h is similar to this. In the field of C + + programming, this simple mechanism is the most commonly used macro function application.

In addition, there is another way to ensure that the header file is compiled only once: #pragma once. Just write this precompiled instruction at the beginning to ensure that all header files are included and compiled only once. However #pragma once is compiler-dependent, some compilers support, and some compilers do not, but most compilers support this precompiled directive. #ifndef, #define, #endif是C the macro definition in the/c++ language, all compilers that support the C + + language are valid, and if you write a cross-platform program, it is best to use a macro to avoid duplicate inclusion of the header file.

(3) Debug with Assert assertion macro

Once you've written your program, stepping into the test every path seems pretty good, but it may not be realistic, and it's a good idea to insert a check statement to validate the value of an expression or variable. The Assert macro is used to accomplish this task, and the Assert macro contains the <assert.h>, with the following syntax:

ASSERT (expression, evaluates to True or FALSE); Example: char * test = new CHAR[25]; ASSERT (Test! = NULL);

Assert indicates this when the pointer is invalid, and in Microsoft Visual Studio, assert can return the application, while the call stack will indicate which line of code has not passed the assertion test, which makes assert a convenient debugging feature.

In most development environments, assert is disabled in release mode, so it displays error messages only in debug mode. Additionally, in some development environments, assert is implemented as a function, not a macro.

(4) Defining macro functions using # define

The preprocessor makes simple substitutions to the text specified by the macro, so you can use the write simple function. Macro functions are often used to perform very simple calculations, and the advantage of macro functions, compared to regular function calls, is that they will be expanded in place prior to compilation, helping to improve the performance of the code (is it a bit of a feeling of inline functions?). )。 Because macros do not consider data types, it is dangerous to use macros, which needs to be taken into account. In addition, the macro is a simple substitution, the macro function must use parentheses to ensure that the replacement function logic is correct, this is the use of macro functions often make mistakes in the point.

It is the macro that does not perform type checking, so the use of macro functions can work on different types of variables. Macro functions do not need to create call stacks, pass parameters, and so on in function calls as regular functions, which typically consume more CPU time than regular functions do. So, for simple functions, you can usually use a macro function. However, macros do not support any form of type safety, and complex macros are not easy to debug. If you want to ensure type safety than generic functions that are independent of type, you can use template functions instead of macro functions, such as to improve performance, you can define inline functions and use the keyword inline, which completely overrides the benefits of the macro function.


Summary

Try not to write macro functions as much as possible, use const variables instead of macro constants, and keep in mind that macros are not type-safe, that the preprocessor does not type-check, that you enclose each variable in a macro function definition, and that you can use a macro to resolve ; Don't forget that you can use assert assertions extensively in debugging, which is helpful for improving code quality.

*************************************************************************************************************** *********************

2. Templates

Templates are probably one of the most powerful and least used (or understood) features in the C + + language.

In C + +, templates allow programmers to define a behavior that is appropriate for different types of objects, such as macros, but macros are not type-safe, and templates are type-safe.

(1) Template declaration Syntax

Template <parameter list>

Template Function/class Declaration

The start of the keyword template banner declaration, followed by the template parameter list. The parameter list contains the keyword typename, which defines the template parameter objecttype, and ObjectType is a placeholder that, when instantiated against an object, replaces it with the object type.

(2) Type of template declaration

A template declaration can be a declaration or definition of a function, a declaration or definition of a class, a declaration or definition of a member function or member class of a class template, the definition of a static data member of a class template, a static data member definition of a class nested in a class template, or a member template definition for a class or class template.

(3) template function

It is not always necessary to specify a type when invoking a template function. Examples are as follows:

Template <typename objecttype>

Const objecttype& Getmax (const objecttype& value1,const objecttype& value2)

{

if (value1 > value2)

return value1;

Else

return value2;

}

An example of using the template specifically:

int Integer1 = 25;

int Integer2 = 50;

Use int MaxValue = Getmax <int> (Integer1, Integer2 );

With the use of int MaxValue = Getmax (Integer1, Integer2 ), the effect is the same. In this case, the compiler does a data type check. However, for a template class, you must explicitly indicate the type. However, it is not possible to make promiscuous types such as Getmax (Integer1, "some string" ). This call causes a compiler error.

(4) template class

A class is a programming unit that encapsulates properties and methods that use those properties. Properties are usually private members. A template class can be useful when an attribute can be of type int or long. When using a template class, you can specify which type of materialization to use. examples are as follows:

Template <typename t>

Class Test

{

Public

void SetValue (const t& newvalue) {Value = newvalue;}

Const t& GetValue () const {return Value;}

Private

T Value;

};

How to use the template class:

Test <int> Test1;

Test1.setvalue (5);

This enables the same property in the template class to have different implementations of the data type, as long as you specify the data type of the properties required by the instantiated object when instantiating the object. In terminology, when using a template, instantiation refers to creating a specific type based on the template declaration and one or more parameters, and the specific type that the instantiation creates is called materialization.

(5) Declaring a template with multiple parameters

The template parameter list contains multiple parameters, and the parameters are separated using commas. Therefore, if you want to declare a generic class to store two types of objects that may be different, you can use the following code:

Template <typename T1, TypeName t2>

Class Test

{

Private

T1 Value1;

T2 Value2;

Public

/*some methods*/

/*constructor*/

Test (const t1& value1, const t2& value2)

{Value1 = value1; Value2 = value2;}

};

Here's how to use it:

Test <int, Int> Test1 (5, 6);//Initialize by constructor.

(6) Declare a template that contains default parameters

Examples are as follows:

Template <typename T1 = int, typename T2 = int>

Class Test

{

Private

T1 Value1;

T2 Value2;

Public

/*some methods*/

/*constructor*/

Test (const t1& value1, const t2& value2)

{Value1 = value1; Value2 = value2;}

};

This is similar to assigning a default parameter value to a function. Therefore, this template, which specifies the default type, can simplify the instantiation process:

Test < > Test1 (5, 6);//Initialize by constructor.

(7) template class and static member

If a class member is declared static, the member is shared by all instances of the class, and the static members of the template class are shared by all instances of a specific materialization. If the template class T contains a static member X, that member is shared across all instances that are materialized for Int. Similarly, it is shared across all instances of a double materialization and is independent of the instances that are materialized by Int. The compiler created two versions of X,x_int for instances that are materialized for int, while x_double for instances of double materialization. That is, for classes that are materialized for each type, the compiler guarantees that its static variables are not affected by other classes. Each materialization of a template class has its own static member. Examples are as follows:

Template <typename t>

Class Teststatic

{

Private

Public

static int staticvalue;

/*some methods*/

};

Static member initialization

Template <typename t> int teststatic<t>:: Staticvalue;

(8) perform a compile-time check using Static_assert

Can be used to set up picky template classes, masking for some type of materialization, using Static_assert for the compilation phase of the check. Examples are as follows:

Template <typename t>

Class Test

{

Private

Public

/*some methods*/

Everythingbutint ()

{

Static_assert (sizeof (T)! = sizeof (int), "No int please!");

}

};


int main ()

{

Test<int> test;

return 0;

}

Compile result output:

Error:no int please!

This compilation result is specified by the Static_assert in the template class.

Summary

Be sure to use templates to implement common concepts, not macros, to use const whenever possible when writing template functions and template classes, and static members of a template class to be shared by all instances of a specific materialization.

*************************************************************************************************************** *********************

Summary

In this article, the preprocessor is described in detail, and when the compiler is run, the preprocessor will first run, convert the directives such as # define, and then replace the text with the preprocessing, but the substitution will be more complex when using macros. By using macro functions, you can make complex text substitutions in the parameters passed to the macro during the compilation phase. It is important to enclose each parameter in the macro in parentheses to make sure that the correct substitution is made. Templates help to write reusable code, which provides developers with a pattern that can be used for different data types. Templates can replace macros and are type-safe. Learning a good template for subsequent use of C + + Standard Template Library STL has a very important conceptual cornerstone significance.

*************************************************************************************************************** *********************

2015-7-30



Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.

Introduction to C + + macros and templates

Related Article

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.