C ++草案标准(N3337)具有以下关于指针转换的内容:
4.10指针转换
2“指向 cv
T
的指针”的右值,其中T
是对象类型,可以转换为“指向 cvvoid
。“将指向 cvT
”的指针转换为“指向 cv的指针 {{ 1}}“指向类型为void
的对象所在的存储位置的开头,就好像该对象是T
类型的派生程度最高的对象(1.8)(即不是基数) class subobject)。
和
4.12布尔转换
1算术,枚举,指针或指向成员类型的指针的右值可以转换为类型
T
的右值。零值,空指针值或空成员指针值转换为false;任何其他值都转换为true
基于以上所述,将函数指针或指针转换为bool
以及int
以及void*
完全可以。
但是,考虑到两者的选择,指针应转换为哪一个?
然后,为什么指向函数的指针转换为bool
,指向bool
的指针转换为int
?
程序:
void*
输出,使用g ++ 4.7.3:
In foo(bool) In foo(void*)
答案 0 :(得分:27)
基于以上所述,将函数指针或指针转换为
int
以及void*
以及bool
完全可以。
引用声明指向对象的指针可以转换为cv void *
。函数不是对象,这会取消转换为cv void *
的资格,只留下bool
。
但是,考虑到两者的选择,指针应转换为哪一个?
它应该转换为const void *
而不是bool
。为什么?那么,准备以超载分辨率开始的旅程(§13.3[over.match] / 2)。当然,重点是我的。
但是,一旦确定了候选函数和参数列表,所有情况下最佳函数的选择都是相同的:
- 首先,候选函数的一个子集(那些具有适当数量的参数并满足 选择某些其他条件)以形成一组可行的函数(13.3.2)。
- 然后根据将每个参数与每个可行函数的相应参数匹配所需的隐式转换序列(13.3.3.1)来选择最佳可行函数。
让我们跳到§13.3.3.1[over.best.ics] / 3,看看隐含的转换序列是什么:
格式良好的隐式转换序列是以下形式之一:
- 标准转换序列(13.3.3.1.1),
- 用户定义的转换序列(13.3.3.1.2)或
- 省略号转换序列(13.3.3.1.3)。
我们对标准转换序列感兴趣。让我们跳转到标准转换序列(§13.3.3.1.1[over.ics.scs]):
1表12总结了第4章中定义的转换,并将它们分为四个不相交的类别:左值转换,资格调整,促销和转换。 [注意:这些类别与值类别,cv限定和数据表示正交:左值变换不会更改类型的cv限定或数据表示;资格调整不会更改类型的值类别或数据表示;促销和转化不会更改该类型的价值类别或cv资格。 - 结束说明]
2 [注意:如第4章所述,标准转换序列是身份转换本身(即无转换)或由其他四个类别中的一到三次转换组成。
重要的部分在/ 2。允许标准转换序列是单个标准转换。这些标准转换列于表12中,如下所示。请注意,指针转换和布尔转换都在那里。
从这里开始,我们学到了一些重要的东西:指针转换和布尔转换具有相同的等级。请记住,当我们前往排序隐式转换序列时(§13.3.3.2[over.ics.rank])。
看/ 4,我们看到:
标准转化顺序按其排名排序:完全匹配是比促销更好的转化,这是一种比转化更好的转化。除非符合以下规则之一,否则具有相同等级的两个转换序列是难以区分的:
- 不将指针,指向成员的指针或std :: nullptr_t转换为bool的转换是 比那更好。
我们以非常明确的陈述形式找到了答案。万岁!