c – 通过const char *构造函数将false转换为object
作者:互联网
我构建了以下最小的示例:
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'
据我所知,如果类A具有构造函数A(T),则可以使用一种类型T而不是类A的实例.在这种情况下,T的值/实例由编译器在对A(T)构造函数的调用中包装.
此外,仅允许一个直接隐式转换,即,即使存在构造符A(B)和B(C),也不插入链A(B(c))来转换类型C的值c.
所以,我的问题:
>为什么在我的例子中将false转换为指针?当然,指针不是对象,但这里仍然有两个隐式转换.正在应用什么规则?
>为什么转换不适用于true?我的直觉是false可以合理地转换为nullptr(参见警告),而没有有意义的指针值为true.
那么,有人可以解释哪些转换规则适用/不适用于上述两个示例?
解决方法:
发布时,C 11具有规则“整数类型的整数常量表达式prvalue,其计算结果为0可以转换为任何指针类型,从而产生该类型的空指针值.” (C 98/03有一个类似措辞的规则,具有相同的净效应).
bool是一个整数类型,false的计算结果为0.所以false是一个有效的空指针常量.
除了这个额外的规则,C没有从整数类型到指针的隐式转换.这就是为什么true不能隐式转换为指针.
但是,C 14更改了空指针常量的定义,因此只有整数文字(而不是整数常量表达式)才有资格. false是一个布尔文字,而不是整数,因此在C 14下,代码将无法编译.
此外,由于标准委员会认为该问题是C 11中的缺陷,因此较新的C 11编译器可能在这方面遵守C 14规则而不将false视为空指针常量.感谢@Destructor追踪issue status.
至于为什么这里似乎允许两个隐式转换:规则不是“最多允许一个隐式转换”.规则是“最多允许一个用户定义的转换”.指针转换(例如将空指针常量转换为空指针值)不归类为用户定义的转换.因此,您的情况下的转换序列是指针转换(bool到const char *),后跟用户定义的转换(const char *到A).
标签:c,implicit-conversion,type-conversion 来源: https://codeday.me/bug/20190727/1555050.html