通过const char *构造函数将false转换为对象 [英] Conversion of false to object via const char * constructor
问题描述
我已经构建了以下最小示例:
I have built the following minimal example:
class A
{
public:
A(const char *s);
private:
const char *p;
};
A::A(const char *s)
: p(s)
{
}
A foo()
{
return false;
}
A bar()
{
return true;
}
使用 g ++(Debian 4.7.2-5 )4.7.2
我得到如下:
t.cc: In function 'A foo()':
t.cc:17:10: warning: converting 'false' to pointer type for argument 1 of 'A::A(const char*)' [-Wconversion-null]
t.cc: In function 'A bar()':
t.cc:23:10: error: could not convert 'true' from 'bool' to 'A'
据我所知,可以使用一个类型 T
如果类 A
具有构造函数 A(T)$ c>,则
$ c>。在这种情况下,T的值/实例由编译器在
A(T)
构造函数的调用中包装。
As far as I know, it is possible to use one type T
instead of an instance of class A
, if class A
has a constructor A(T)
. In this case, the value / instance of T is wrapped by the compiler inside a call to the A(T)
constructor.
此外,只允许一个直接隐式转换,即不插入链 A(B(c))
,以转换值 c即使构造函数
A(B)
和,
存在。 C
> B(C)
Also, only one direct implicit conversion is allowed, i.e. no chain A(B(c))
is inserted to convert a value c
of type C
, even if constructors A(B)
and B(C)
exist.
所以,我的问题:
- 为什么
false
在我的示例中转换为指针?当然,指针不是一个对象,但这里仍然有两个隐式转换。应用什么规则? - 为什么转换不能与
true
一起使用?我的直觉是,false
可以合理地转换为nullptr
(另见警告),而没有意义因此,有人可以解释一下什么转换规则适用于您的转换规则。true
。
- Why is
false
converted to a pointer in my example? Sure, a pointer is not an object, but there are still two implicit conversions here. What rule is being applied? - Why does the conversion not work with
true
? My intuition is thatfalse
can be reasonably converted to anullptr
(see also the warning), whereas there is no meaningful pointer value fortrue
.
$ b /不适用于上面的两个例子?
So, could someone explain what conversion rules apply / do not apply to the two examples above?
推荐答案
发布时,C ++ 11有一个规则整数类型,其计算结果 0
可以转换为任何指针类型,产生该类型的空指针值。 (C ++ 98/03有一个类似的措辞规则,具有相同的净效果)。
As published, C++ 11 has the rule "an integral constant expression prvalue of integer type which evaluates to 0
can be converted to any pointer type, yielding the null pointer value of that type." (C++98/03 had a similarly worded rule with the same net effect).
bool
整数类型, false
计算为 0
。因此 false
是一个有效的空指针常量。
bool
is an integer type, and false
evaluates to 0
. So false
is a valid null pointer constant.
除了这个额外的规则,C ++没有从积分类型到指针。这是为什么 true
不能隐式转换为指针。
Apart from this extra rule, C++ has no implicit conversions from integral types to pointers. Which is why true
cannot implicitly be converted to a pointer.
但是,C ++ 14改变了空指针常量,以便只有整数常量(而不是整数常量表达式)限定。 false
是一个布尔文字,而不是一个整数,因此在C ++ 14下,代码将无法编译。
However, C++14 changed the definition of a null pointer constant so that only integer literals (and not integral constant expressions) qualify. false
is a boolean literal, not an integer one, so under C++14, the code will not compile.
此外,由于该问题被标准委员会认为是C ++ 11中的一个缺陷,较新的C ++ 11编译器在这方面可能服从C ++ 14规则,不能处理 false
作为空指针常量。感谢 @Destructor 跟踪问题状态。
Furthermore, since the issue was recognised by the standard committee as a defect in C++11, newer C++11 compilers are likely to obey the C++14 rules in this regard and not treat false
as a null pointer constant. Thanks to @Destructor for tracking down the issue status.
至于为什么在这里似乎允许两个隐式转换:规则不是至多一个隐式转换是允许的。规则是最多只允许一次用户定义转化。指针转换(例如将空指针常量转换为空指针值)不会归类为用户定义的转换。所以你的情况下的转换序列是一个指针转换( bool
到 const char *
),后跟一个用户定义转换( const char *
到 A
)。
As to why two implicit conversions seem to be allowed here: the rule is not "at most one implicit conversion is allowed." The rule is "at most one user-defined conversion is allowed." Pointer conversions (such as converting a null pointer constant to a null pointer value) are not classified as user-defined conversions. So the conversion sequence in your case is a pointer conversion (bool
to const char *
) followed by a user-defined conversion (const char *
to A
).
这篇关于通过const char *构造函数将false转换为对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!