Replacing text macros
来自cppreference.com
< cpp | preprocessor
该页由英文版wiki使用Google Translate机器翻译而来。
该翻译可能存在错误或用词不当。鼠标停留在文本上可以看到原版本。你可以帮助我们修正错误或改进翻译。参见说明请点击这里. |
支持文本预处理器的宏替换。功能还支持文本宏替换.
原文:
The preprocessor supports text macro replacement. Function-like text macro replacement is also supported.
目录 |
[编辑] 语法
#define identifier replacement-list
|
(1) | ||||||||
#define identifier( parameters ) replacement-list
|
(2) | ||||||||
#define identifier( parameters, ... ) replacement-list
|
(3) | ||||||||
#define identifier( ... ) replacement-list
|
(4) | ||||||||
#undef identifier
|
(5) | ||||||||
[编辑] 解释
[编辑] NJ指令
#define
指令作为宏定义identifier,这是指示编译器将取代连续出现identifierreplacement-list,可以选择另外的处理。如果标识符已被定义为任何类型的宏,该方案是格式错误的. 原文:
The
#define
directives define the identifier as macro, that is instruct the compiler to replace all successive occurrences of identifier with replacement-list, which can be optionally additionally processed. If the identifier is already defined as any type of macro, the program is ill-formed. [编辑] 宏对象
类似对象的宏替换出现的每一个定义identifierreplacement-list。版本(1)
#define
指令的行为完全一样的.原文:
Object-like macros replace every occurrence of defined identifier with replacement-list. Version (1) of the
#define
directive behaves exactly like that.[编辑] 函数宏
函数宏的定义identifier取代每个出现replacement-list,另外一些参数,然后更换相应出现的任何parameters在replacement-list。参数的个数参数的宏定义(parameters)或程序的数量是病形成的必须是相同的。如果标识符是不是在功能符号,即没有后面的括号本身,它不会取代可言
原文:
Function-like macros replace each occurrence of defined identifier with replacement-list, additionally taking a number of arguments, which then replace corresponding occurrences of any of the parameters in the replacement-list. The number of arguments must be the same as the number of arguments in macro definition (parameters) or the program is ill-formed. If the identifier is not in functional-notation, i.e. does not have parentheses after itself, it is not replaced at all.
版本(2)
#define
指令定义了一个简单的函数宏.原文:
Version (2) of the
#define
directive defines a simple function-like macro.版本(3)
#define
指令定义了一个函数宏与可变数目的参数。可以访问使用__VA_ARGS__
标识符,然后将其替换带参数,供给与该标识符以被替换的附加参数.原文:
Version (3) of the
#define
directive defines a function-like macro with variable number of arguments. The additional arguments can be accessed using __VA_ARGS__
identifier, which is then replaced with arguments, supplied with the identifier to be replaced.版本(4)
#define
指令定义了一个函数宏与可变数目的参数,但没有任何一个正式的参数。 __VA_ARGS__
标识符,然后将其替换为提供的标识符被替换的参数,这些参数可以被访问.原文:
Version (4) of the
#define
directive defines a function-like macro with variable number of arguments, but no regular arguments. The arguments can be accessed only with __VA_ARGS__
identifier, which is then replaced with arguments, supplied with identifier to be replaced.[编辑] NJ和NJ运营商
在函数宏,
#
运营商replacement-list的标识符,在运行前通过参数替换的标识符和包围在引号中,从而有效地创建一个字符串常量。此外,预处理器将backslahes逃脱引号嵌入字符串常量,如果有的话,双倍的反斜线内的字符串(如需要)。所有的开头和结尾的空格被删除,并在文本中间的任何序列的空白(但不能在嵌入式字符串文字)被折叠成一个单一的空间。此操作被称为“字串化”。如果不是一个有效的字符串文字的字串化的结果是,该行为是未定义.原文:
In function-like macros, a
#
operator before an identifier in the replacement-list runs the identifier through parameter replacement and encloses the result in quotes, effectively creating a string literal. In addition, the preprocessor adds backslahes to escape the quotes surrounding embedded string literals, if any, and doubles the backslashes within the string as necessary. All leading and trailing whitespace is removed, and any sequence of whitespace in the middle of the text (but not inside embedded string literals) is collapsed to a single space. This operation is called "stringification". If the result of stringification is not a valid string literal, the behavior is undefined.一个
##
运营商之间的任何两个连续的标识符在replacement-list运行参数替换两个标识符,然后连接结果。该操作被称为“级联”或“标记粘贴”。只有形成一个有效的令牌的令牌一起可能被粘贴,形成了长标识符:标识符,形成一个数字的,数字或运算符+
和=
,形成了+=
。因为注释从文本在宏替换被认为是之前不会创建一个注释可以通过粘贴/
和*
。如果级联的结果是不是一个有效的令牌,该行为是未定义.原文:
A
##
operator between any two successive identifiers in the replacement-list runs parameter replacement on the two identifiers and then concatenates the result. This operation is called "concatenation" or "token pasting". Only tokens that form a valid token together may be pasted: identifiers that form a longer identifier, digits that form a number, or operators +
and =
that form a +=
. A comment cannot be created by pasting /
and *
because comments are removed from text before macro substitution is considered. If the result of concatenation is not a valid token, the behavior is undefined.[编辑] NJ指令
#undef
指令取消定义identifier,identifier#define
指令取消以前定义的。如果标识符不相关的宏,该指令被忽视原文:
The
#undef
directive undefines the identifier, that is cancels previous definition of the identifier by #define
directive. If the identifier does not have associated macro, the directive is ignored.[编辑] 预定义宏
下面的宏的名称是任何翻译单元中预定义.
原文:
The following macro names are predefined in any translation unit.
__cplusplus |
扩展到价值199711L(至 C++11)或201103L(C++11 起) 原文: expands to value 199711L(至 C++11) or 201103L(C++11 起) (常量宏) |
__STDC_HOSTED__ (C++11) |
扩展到整数常量1的执行,如果托管(下运行的OS),0独立(没有OS) 原文: expands to the integer constant 1 if the implementation is hosted (runs under an OS), 0 if freestanding (runs without an OS) (常量宏) |
__FILE__ |
扩展到当前文件的名称,作为一个字符串文字 原文: expands to the name of the current file, as a character string literal (常量宏) |
__LINE__ |
扩展的源文件中的行数,整数常量 原文: expands to the source file line number, an integer constant (常量宏) |
__DATE__ |
扩展到翻译之日起,字符串文字“MMM DD YYYY”的形式。该月的名称是因为如果由std::asctime()生成 原文: expands to the date of translation, a character string literal of the form "Mmm dd yyyy". The name of the month is as if generated by std::asctime() (常量宏) |
__TIME__ |
扩展到翻译的时候,一个字符串文字的形式“HH:MM:SS” 原文: expands to the time of translation, a character string literal of the form "hh:mm:ss" (常量宏) |
以下额外的宏的名称可能是预定义的实现.
原文:
The following additional macro names may be predefined by the implementations.
__STDC__ |
实现定义的值,如果存在的话 原文: implementation-defined value, if present (常量宏) |
__STDC_VERSION__ (C++11) |
实现定义的值,如果存在的话 原文: implementation-defined value, if present (常量宏) |
__STDC_ISO_10646__ (C++11) |
扩展到一个整数常量的形式 yyyymmL ,如果wchar_t使用Unicode,日期显示的最新版本的Unicode支持原文: expands to an integer constant of the form yyyymmL , if wchar_t uses Unicode, the date indicates the latest revision of Unicode supported(常量宏) |
__STDC_MB_MIGHT_NEQ_WC__ (C++11) |
扩展到1广泛的基本字符集的字符编码可能不等于自己狭隘的编码 原文: expands to 1 if wide character encoding of the basic character set may not equal their narrow encoding (常量宏) |
__STDCPP_STRICT_POINTER_SAFETY__ (C++11) |
扩展到1如果执行严格的std::pointer_safety 原文: expands to 1 if the implementation has strict std::pointer_safety (常量宏) |
__STDCPP_THREADS__ (C++11) |
扩展到1如果该程序可以有一个以上的执行线程 原文: expands to 1 if the program can have more than one thread of execution (常量宏) |
这些宏的值(除
__FILE__
和__LINE__
)保持不变,在整个翻译单元。试图重新定义或者取消这些宏的结果未定义的行为.原文:
The values of these macros (except for
__FILE__
and __LINE__
) remain constant throughout the translation unit. Attempts to redefine or undefine these macros result in undefined behavior.注:在每一个函数体的范围,有一个特殊的功能,本地的预定义变量名为__func__(C++11 起),定义为静态字符数组中的函数实现定义的格式的名称。这不是一个宏,但它一起使用
__FILE__
和__LINE__
,如由assert.原文:
Note: in the scope of every function body, there is a special function-local predefined variable named __func__(C++11 起), defined as a static character array holding the name of the function in implementation-defined format. It is not a preprocessor macro, but it is used together with
__FILE__
and __LINE__
, e.g. by assert.[编辑] 示例
#include <iostream> //make function factory and use it #define FUNCTION(name, a) int fun_##name() { return a;} FUNCTION(abcd, 12); FUNCTION(fff, 2); FUNCTION(kkk, 23); #undef FUNCTION #define FUNCTION 34 #define OUTPUT(a) std::cout << #a << '\n' int main() { std::cout << "abcd: " << fun_abcd() << '\n'; std::cout << "fff: " << fun_fff() << '\n'; std::cout << "kkk: " << fun_kkk() << '\n'; std::cout << FUNCTION << '\n'; OUTPUT(million); //note the lack of quotes }
输出:
abcd: 12 fff: 2 kkk: 23 34 million