加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c – 通过const char *构造函数将false转换为object

发布时间:2020-12-16 10:02:44 所属栏目:百科 来源:网络整理
导读:我构建了以下最小的示例: 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
我构建了以下最小的示例:

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).

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读