Implicit conversions
来自cppreference.com
该页由英文版wiki使用Google Translate机器翻译而来。
该翻译可能存在错误或用词不当。鼠标停留在文本上可以看到原版本。你可以帮助我们修正错误或改进翻译。参见说明请点击这里. |
进行隐式转换时使用某种类型的
T1
的表达,但接受不接受这种类型的背景下,一些其他类型T2
,特别是:原文:
Implicit conversions are performed whenever an expression of some type
T1
is used in context that does not accept that type, but accepts some other type T2
, in particular:- 声明
T2
作为参数调用函数时,表达式时使用的参数.原文:When the expression is used as the argument when calling a function that is declared withT2
as parameter. - 当表达式作为操作数与运营商,预计
T2
原文:When the expression is used as an operand with an operator that expectsT2
- 当初始化一个新的
T2
类型的对象,包括return
声明一个函数返回T2
.原文:When initializing a new object of typeT2
, includingreturn
statement in a function returningT2
. - 当表达式用于在
switch
语句(T2
是积分型)原文:When the expression is used in aswitch
statement (T2
is integral type) -
if
声明表达式时使用的一个循环(T2
是bool)原文:When the expression is used in anif
statement or a loop (T2
is bool)
该计划是良好的(编译)仅当存在一个明确的“隐式转换序列”从
T1
T2
的 原文:
The program is well-formed (compiles) only if there exists one unambiguous implicit conversion sequence from
T1
to T2
. 如果有多个被调用的函数或运算符的重载,后是建立从T1到每个可用T2的隐式转换序列,重载决议规则决定了编译过载.
原文:
If there are multiple overloads of the function or operator being called, after the implicit conversion sequence is built from T1 to each available T2, 重载决议 rules decide which overload is compiled.
目录 |
[编辑] 转换的顺序
隐式转换序列由以下的顺序是:
原文:
Implicit conversion sequence consists of the following, in this order:
1)
零个或一个“标准转换序列”
原文:
zero or one standard conversion sequence
2)
零个或一个“用户定义的转换”
3)
零个或一个标准转换序列
原文:
zero or one standard conversion sequence
考虑的参数的构造函数或用户定义的转换功能时,只有一个标准转换序列是允许的(否则用户定义的转换,可以有效地链接)。当从一个内置的类型转换到另一个内置的类型,只有一个标准转换序列允许.
原文:
When considering the argument to a constructor or to a user-defined conversion function, only one standard conversion sequence is allowed (otherwise user-defined conversions could be effectively chained). When converting from one built-in type to another built-in type, only one standard conversion sequence is allowed.
标准转换序列由以下的顺序是:
原文:
A standard conversion sequence consists of the following, in this order:
1)
零个或一个“左值变换”
2)
零个或一个“数字升级”或“数字转换”
原文:
zero or one numeric promotion or numeric conversion
3)
零个或一个“资格调整”
用户定义的转换包括:
原文:
A user-defined conversion consists of:
@ * @零个或一个非显式的单参数的构造函数或显式转换函数调用
原文:
@*@ zero or one non-explicit single-argument constructor or non-explicit conversion function call
表达式
e
被说成是“隐式转换为T2
”当且仅当声明T2 t=e;是良好的(可以编译),一些发明的临时t
。请注意,这是T2 t(e),明确的构造函数和转换功能,另外考虑不同.原文:
An expression
e
is said to be implicitly convertible to T2
if and only if the declaration T2 t=e; is well-formed (can be compiled), for some invented temporary t
. Note that this is different from T2 t(e), where explicit constructors and conversion functions would additionally be considered.唯一的例外是上面的规则是在以下五个上下文(C++11 起),类型bool特殊的隐式转换调用
原文:
One exception is the above rule is the special implicit conversion invoked in the following five contexts (C++11 起), where type bool is expected:
- 控制表达式
if
,while
,for
原文:controlling expression ofif
,while
,for
- 逻辑运算符
!
,&&
||
- 条件运算符
?:
-
static_assert
-
noexcept
-
在这样的背景下,如果声明bool t(e);建立良好的隐式转换序列。即,显式的用户定义的转换函数,如
explicit T::operator bool() const;
被认为。这样的表达e
被说成是“上下文转换为布尔.原文:
in such contexts, implicit conversion sequence is built if the declaration bool t(e); is well-formed. that is, the explicit user-defined conversion function such as
explicit T::operator bool() const;
is considered. Such expression e
is said to be contextually convertible to bool.[编辑] 左值的转换
左值转换时所应用的左值参数(如参照对象)的背景下,右值(如数字),预计.
原文:
Lvalue transformations are applied when lvalue argument (e.g. reference to an object) is used in context where rvalue (e.g. a number) is expected.
[编辑] 左值到右值的转换
一个glvalue任何非功能,非数组类型
T
可以隐式地转换为相同类型的prvalue。 T
是一种非类类型,这种转换也移除cv修饰符。除非遇到非计算环境(操作数的大小,typeid的,noexcept,或decltype),这种转换有效地复制构造一个临时对象类型T
使用原来的glvalue作为构造函数的参数,并,临时对象作为prvalue返回的。 ,如果glvalue的类型std::nullptr_t,prvalue是空指针常量nullptr
.原文:
A glvalue of any non-function, non-array type
T
can be implicitly converted to prvalue of the same type. If T
is a non-class type, this conversion also removes cv-qualifiers. Unless encountered in unevaluated context (in an operand of sizeof, typeid, noexcept, or decltype), this conversion effectively copy-constructs a temporary object of type T
using the original glvalue as the constructor argument, and that temporary object is returned as a prvalue. If the glvalue has the type std::nullptr_t, the resulting prvalue is the null pointer constant nullptr
.[编辑] 数组到指针的转换
一个左值或右值类型的数组“
N
T
”或“未知边界的T
阵列”可以被隐式地转换为一个prvalue的指针“类型T
”。结果指针的数组的第一个元素是指.原文:
A lvalue or rvalue of type "array of
N
T
" or "array of unknown bound of T
" can be implicitly converted to a prvalue of type "pointer to T
". The resulting pointer refers to the first element of the array.[编辑] 函数指针
左值可以隐式转换函数类型
T
到prvalue指向该函数的指针。这并不适用于非静态成员函数,因为非静态成员函数的左值,不存在.原文:
An lvalue of function type
T
can be implicitly converted to a prvalue pointer to that function. This does not apply to non-static member functions because lvalues that refer to non-static member functions do not exist.[编辑] 数字的促销活动
[编辑] 积分的推广
Prvalues小的整类型(如char),可转换为更大的整数类型(如int),prvalues的。特别是,算术运算符不接受类型的小于int作为参数,并整体促销会自动应用。这种转换总是保留的价值.
原文:
Prvalues of small integral types (such as char) may be converted to prvalues of larger integral types (such as int). In particular, 算术运算符 do not accept types smaller than int as arguments, and integral promotions are automatically applied. This conversion always preserves the value.
下列隐式转换被归类为整型的提升
原文:
The following implicit conversions are classified as integral promotions:
signed char
或signed short
可以转换为int.原文:signed char
orsigned short
can be converted to int.
unsigned char
或unsigned short
可以转换为unsigned int.原文:unsigned char
orunsigned short
can be converted to unsigned int.
char
可以转换为int或unsigned int的基本类型:signed char或unsigned char(见上文)原文:char
can be converted to int or unsigned int depending on the underlying type: signed char or unsigned char (see above)
wchar_t
,char16_t
,char32_t
可以转化为第一种类型从下面的列表中能够保持他们的整个值范围:int,unsigned int,long,unsigned long,long long,unsigned long long.原文:wchar_t
,char16_t
, andchar32_t
can be converted to the first type from the following list able to hold their entire value range: int, unsigned int, long, unsigned long, long long, unsigned long long.
- 从下面的列表中能够保持其整个价值范围的“”无作用域的枚举类型是不固定的,其基本型可转换为第一类:int,unsigned int,long,unsigned long,long long,或unsigned long long。如果该值的范围是更大的,没有整体的促销活动.原文:An unscoped enumeration type whose underlying type is not fixed can be converted to the first type from the following list able to hold their entire value range: int, unsigned int, long, unsigned long, long long, or unsigned long long. If the value range is greater, no integral promotions apply.
-
- 促进基础类型可以转换为一个“无作用域的枚举”类型的基础类型是固定的。 (C++11 起)原文:An unscoped enumeration type whose underlying type is fixed can be converted to its promoted underlying type. (C++11 起)
-
- A“位域类型”可以转换为int,如果它能够代表整个位域的值的范围,否则unsigned int,如果它可以代表整个位域的值的范围,否则无积分优惠.原文:A bitfield type can be converted to int if it can represent entire value range of the bitfield, otherwise to unsigned int if it can represent entire value range of the bitfield, otherwise no integral promotions apply.
-
- 与该值可以被转换成的类型boolintfalse成为0和true成为1.原文:The type bool can be converted to int with the value false becoming 0 and true becoming 1.
-
[编辑] 浮点推广
可转换类型float甲prvalue prvalue类型double。值不改
原文:
A prvalue of type float can be converted to prvalue of type double. The value does not change.
[编辑] 数字的转换
不同的促销活动,可能会改变数字转换的值,与潜在的精度损失.
原文:
Unlike the promotions, numeric conversions may change the values, with potential loss of precision.
[编辑] 积分转换
一个prvalue一个整数类型或无作用域的枚举类型可以转换为任何其他整数类型。如果转换被列在积分促销,它是一种促进,而不是转换.
原文:
A prvalue of an integer type or of an unscoped enumeration type can be converted to any other integer type. If the conversion is listed under integral promotions, it is a promotion and not a conversion.
- 如果目标类型是无符号的,所产生的价值是值模2n
n是数位用来表示目标类型。在2的补码运算(C + +编译器可在所有平台上使用),这种转换是一个no-op,除了截断如果目标类型是小的原文:If the destination type is unsigned, the resulting value is the value modulo 2n
where n is the number of bits used to represent the destination type. In 2's complement arithmetic (used on all platforms where C++ compilers are available), this conversion is a no-op, except for the truncation if the destination type is to small.
-
- 如果目标类型是有符号的值不会改变,如果源整数可以表示目标类型的。否则,其结果是实现定义的.原文:If the destination type is signed, the value does not change if the source integer can be represented in the destination type. Otherwise the result is implementation-defined.
-
- 如果源类型为bool,被转换的值false到零,并转换的目标类型(注意,如果目标类型是true,这是一个整数的推广,而不是一个整数的转换)的值1的值int原文:If the source type is bool, the value false is converted to zero and the value true is converted to the value one of the destination type (note that if the destination type is int, this is an integer promotion, not an integer conversion)
-
- 如果目标类型是bool,这是一个布尔值转换(见下文)原文:If the destination type is bool, this is a boolean conversion (see below)
-
[编辑] 浮点转换
一个prvalue的浮点类型可以转换为任何其他浮点类型prvalue。如果转换被列入下浮点促销,它是一种促进,而不是转换.
原文:
A prvalue of an floating-point type can be converted to prvalue of any other floating-point type. If the conversion is listed under floating-point promotions, it is a promotion and not a conversion.
- 如果源值可以精确表示目标类型,它不改原文:If the source value can be represented exactly in the destination type, it does not change.
-
- 如果源值是表示两个值的目标类型,其结果是这两个值之一(这是实现定义的是哪一个)原文:If the source value is between two representable values of the destination type, the result is one of those two values (it is implementation-defined which one)
-
- 否则,该行为是未定义.原文:Otherwise, the behavior is undefined.
-
[编辑] 浮动 - 整体转换
- 一个prvalue的浮点类型可以转换为任何整数类型的prvalue。的小数部分被截断,即,小数部分被丢弃。如果该值不能放入目标类型,其行为是不确定的。如果目标类型是bool,这是一个布尔值转换(见下文).原文:A prvalue of floating-point type can be converted to prvalue of any integer type. The fractional part is truncated, that is, the fractional part is discarded. If the value can not fit into the destination type, the behavior is undefined. If the destination type is bool, this is a boolean conversion (see below).
-
- 一个prvalue的整数或无作用域的枚举类型可以转换为任何浮点类型的prvalue。如果该值不能正确地表示,这是实现定义的最接近是否高于或最接近的低表示的值将被选中。如果该值不能放入目标类型,其行为是不确定的。如果源类型为bool,被转换的值false为零,和的值被转换成一个true.原文:A prvalue of integer or unscoped enumeration type can be converted to prvalue of any floating-point type. If the value can not be represented correctly, it is implementation defined whether the closest higher or the closest lower representable value will be selected. If the value can not fit into the destination type, the behavior is undefined. If the source type is bool, the value false is converted to zero, and the value true is converted to one.
-
[编辑] 指针转换
- “空指针常量”NULL或任何其他prvalue的积分类型,其值为零或任何prvalue的类型std::nullptr_t,包括“空指针文字nullptr,可转换为任何指针类型,其结果是该类型的空指针值。允许这样的转换(称为“空指针转换”转换TOT的cv-限定的类型为单次转换,也就是说,它不认为是一个组合的数字和合格的转换).原文:The null pointer constant NULL or any other prvalue of integral type that evaluates to zero or any prvalue of type std::nullptr_t, including the null pointer literal nullptr, can be converted to any pointer type, and the result is the null pointer value of that type. Such conversion (known as 'null pointer conversion is allowed to conver tot a cv-qualified type as a single conversion, that is, it's not considered a combination of numeric and qualifying conversions).
-
- 阿prvalue指向任何(可选CV合格)对象类型
T
可以被转换成一个prvalue指针,以(相同品种合格)的void。T
如果不是的运行时类型指向的对象,所得到的指针调整为指向最派生的对象所占用的存储的开始。如果原来的指针是一个空指针值,其结果是一个空指针目标类型.原文:A prvalue pointer to any (optionally cv-qualified) object typeT
can be converted to a prvalue pointer to (identically cv-qualified) void. IfT
is not the runtime type of the pointed-to object, the resulting pointer is adjusted to point to the start of the storage occupied by the most-derived object. If the original pointer is a null pointer value, the result is a null pointer value of the destination type.
-
- 一个prvalue指向一个(任选品种合格的)派生类类型可以转换为prvalue其可访问的,明确的(相同的CV合格)的基类的指针。转换的结果是一个指针所指向的对象的基类的子对象内。空指针值转换为目标类型的空指针值.原文:A prvalue pointer to a (optionally cv-qualified) derived class type can be converted to prvalue pointer to its accessible, unambiguous (identically cv-qualified) base class. The result of the conversion is a pointer to the base class subobject within the pointed-to object. The null pointer value is converted to the null pointer value of the destination type.
-
[编辑] 指针到成员的转换
- “空指针常数NULL或任何其他prvalue的积分类型,其值为零或任何prvalue的std::nullptr_t的类型,包括”空指针文字nullptr,可以转换为任何指针到成员的类型,和结果是该类型的空指针值。允许这样的转换(称为“空指针转换”转换TOT的cv-限定的类型为单次转换,也就是说,它不认为是一个组合的数字和合格的转换).原文:The null pointer constant NULL or any other prvalue of integral type that evaluates to zero or any prvalue of type std::nullptr_t, including the null pointer literal nullptr, can be converted to any pointer-to-member type, and the result is the null pointer value of that type. Such conversion (known as 'null pointer conversion is allowed to conver tot a cv-qualified type as a single conversion, that is, it's not considered a combination of numeric and qualifying conversions).
-
- 在基类中
T
某种类型的B
成员Prvalue指针可以转换,以prvalue相同类型的T
在它的派生类D
成员的指针。B
是无法访问的,如果含糊不清,或虚拟基础D
或是一些中间虚基类D
的基础,转化是形成不良(不能编译)。结果指针被解除引用一个D
对象,B
基地内,D
对象的子对象的,它会访问该成员。空指针值转换为目标类型的空指针值.原文:Prvalue pointer to member of some typeT
in a base classB
can be converted to prvalue pointer to member of the same typeT
in its derived classD
. IfB
is inaccessible, ambiguous, or virtual base ofD
or is a base of some intermediate virtual base ofD
, the conversion is ill-formed (won't compile). The resulting pointer can be dereferenced with aD
object, and it will access the member within theB
base subobject of thatD
object. The null pointer value is converted to the null pointer value of the destination type.
-
[编辑] 布尔转换
Prvalues可以转换为整数,浮点,无作用域的枚举,指针,指针到成员类型的prvalues类型bool.
原文:
Prvalues of integral, floating-point, unscoped enumeration, pointer, and pointer-to-member types can be converted to prvalues of type bool.
零值(整型,浮点型点,无作用域的枚举)和空指针和空指针到成员的值成为false。所有其他值成为true.
原文:
The value zero (for integral, floating-point, and unscoped enumeration) and the null pointer and the null pointer-to-member values become false. All other values become true.
prvalue类型std::nullptr_t包括
nullptr
,可以转换prvalue类型bool。所得到的值是false。 (C++11 起)原文:
Prvalue of type std::nullptr_t, including
nullptr
, can be converted to prvalue of type bool. The resulting value is false. (C++11 起)[编辑] 资格转换
- 类型甲prvalue
T
可以转换为prvalue更cv限定相同类型T
(换句话说,可以添加常量性)的指针
- 类型甲prvalue
- 一个prvalue指针类型的CV-限定的类型
T
在课堂上X
的成员可以转换为prvalue指针成员CV-限定的类型T
类X
.原文:A prvalue of type pointer to member of cv-qualified typeT
in classX
can be converted to prvalue pointer to member of more cv-qualified typeT
in classX
.
-
“”CV合格的手段
- “不合格”类型可以转换
const
原文:unqualified type can be converted toconst
- “不合格”类型可以转换
volatile
原文:unqualified type can be converted tovolatile
- “不合格”类型可以转换
const volatile
原文:unqualified type can be converted toconst volatile
-
const
类型可以转换const volatile
原文:const
type can be converted toconst volatile
-
volatile
类型可以转换const volatile
原文:volatile
type can be converted toconst volatile
-
对于多层次的指针,有下列限制:
原文:
For multi-level pointers, the following restrictions apply:
一个多层次的
0合格的指针的指针的指针cv1
1,... cv1
n-1合格的cv1
n
0合格的指针的指针的指针cv2
1... cv2
n-1cv2
n合格的
P1
合格的cv10合格的指针的指针的指针cv1
1,... cv1
n-1合格的cv1
n
T
合格的指针转换为一个多层次的P1
合格的cv20合格的指针的指针的指针cv2
1... cv2
n-1cv2
n合格的
T
只有合格的指针原文:
A multilevel pointer
0-qualified pointer to cv1
1-qualified pointer to ... cv1
n-1-qualified pointer to cv1
n-qualified
0-qualified pointer to cv2
1-qualified pointer to ... cv2
n-1-qualified pointer to cv2
n-qualified
P1
which is cv10-qualified pointer to cv1
1-qualified pointer to ... cv1
n-1-qualified pointer to cv1
n-qualified
T
is convertible to a multilevel pointer P1
which is cv20-qualified pointer to cv2
1-qualified pointer to ... cv2
n-1-qualified pointer to cv2
n-qualified
T
only if- 水平
n
的数目是相同的两个指针原文:The number of levelsn
is the same for both pointers - 在P1的一些电平(电平零除外)如果有一个const在cv1
k资格,有一个在相同等级的P2constcv2
k原文:If there is a const in the cv1
k qualification at some level (other than level zero) of P1, there is a const in the same level cv2
k of P2 - 如果有一个在一定程度上(除零级)的P1volatile在cv1
k资格,有一个在相同的P2volatilelevelcv2
k原文:If there is a volatile in the cv1
k qualification at some level (other than level zero) of P1, there is a volatile in the same cv2
klevel of P2 - 如果在一定程度上是不同的
k
的cv资格之间P1
P2
,那么就必须是一个const在每一个(其他零级以上)P2
起来,直到K:cv2
1, cv2
2 ... cv2
k.原文:If at some levelk
the cv-qualifications are different betweenP1
andP2
, then there must be a const at every single level (other than level zero) ofP2
up until k: cv2
1, cv2
2 ... cv2
k. - 规则同样适用于多层次的成员,多层次混合的对象和指向成员的指针的指针的指针.原文:Same rules apply to multi-level pointers to members and multi-level mixed pointers to objects and pointers to members.
- 零级解决非多层次的资格转换的规则.原文:Level zero is addressed by the rules for non-multilevel qualification conversions.
-
特别是,这不允许从
T**
转换const T**
,但允许转换const T* const*
.原文:
In particular, this forbids the conversion from
T**
to const T**
, but conversion to const T* const*
is allowed.[编辑] 安全BOOL问题
直到引进的显式转换函数在C + +11,设计一个类,应该是在布尔上下文中使用(例如if(obj) { ...提出了一个问题:给定一个用户定义的转换功能,如T::operator bool() const;,隐式转换序列允许一个另外的标准转换序列后,该函数调用,这意味着可以转换所得boolint,允许这样的代码作为obj << 1;或int i=test;.
原文:
Until the introduction of explicit conversion functions in C++11, designing a class that should be usable in boolean contexts (e.g. if(obj) { ... presented a problem: given a user-defined conversion function, such as T::operator bool() const;, the implicit conversion sequence allowed one additional standard conversion sequence after that function call, which means the resultant bool could be converted to int, allowing such code as obj << 1; or int i=test;.
一个早期的解决方案中可以看到std::basic_ios,这定义operator!和operator void*()(至 C++11)的,从而使代码如if(std::cin) {...编译,因为void*转换为bool,但int n = std::cout;不编译void*是转换为int。delete std::cout;编译的代码,如仍允许废话,和之前的很多C + +11第三方库的设计与更精细的溶液,被称为Safe Bool idiom.
原文:
One early solution for this can be seen in std::basic_ios, which defines operator! and operator void*()(至 C++11), so that the code such as if(std::cin) {... compiles because void* is convertible to bool, but int n = std::cout; does not compile because void* is not convertible to int. This still allows nonsense code such as delete std::cout; to compile, and many pre-C++11 third party libraries were designed with a more elaborate solution, known as the Safe Bool idiom.