关于c ++:为什么将指向int的指针转换为void *而将指向函数的指针转换为bool?

Why does pointer to int convert to void* but pointer to function convert to bool?

C ++草案标准(N3337)具有以下有关指针转换的信息:

4.10 Pointer conversions

2 An rvalue of type"pointer to cv T," where T is an object type, can be converted to an rvalue of type"pointer to cv void." The result of converting a"pointer to cv T" to a"pointer to cv void" points to the start of the storage location where the object of type T resides, as if the object is a most derived object (1.8) of type T (that is, not a base class subobject).

4.12 Boolean conversions

1 An rvalue of arithmetic, enumeration, pointer, or pointer to member type can be converted to an rvalue of type bool. A zero value, null pointer value, or null member pointer value is converted to false; any other value is converted to true

基于上述情况,将函数指针或指向int的指针转换为void*bool完全可以。

但是,考虑到两者的选择,指针应转换为哪一个?

然后,为什么将指向函数的指针转换为bool而将指向int的指针转换为void*

程序:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <iostream>
using namespace std;

void foo(const void* ptr)
{
   std::cout <<"In foo(void*)" << std::endl;
}

void foo(bool b)
{
   std::cout <<"In foo(bool)" << std::endl;
}

void bar()
{
}

int main()
{
   int i = 0;
   foo(&bar);
   foo(&i);
   return 0;
}

使用g ++ 4.7.3的输出:

1
2
In foo(bool)
In foo(void*)


Based on the above, it is perfectly OK to convert a function pointer or a pointer to an int to a void* as well as bool.

引号指出可以将指向对象的指针转换为cv void *。函数不是对象,因此将转换为cv void *的资格,仅保留bool

However, given the choice of both, which one should a pointer convert to?

它应该在bool上转换为const void *。为什么?好吧,为从超载分辨率(§13.3[over.match] / 2)开始的旅程做准备。当然要强调我的。

But, once the candidate functions and argument lists have been identified, the selection of the best function is the same in all cases:

— First, a subset of the candidate functions (those that have the proper number of arguments and meet
certain other conditions) is selected to form a set of viable functions (13.3.2).

— Then the best viable function is selected based on the implicit conversion sequences (13.3.3.1) needed to match each argument to the corresponding parameter of each viable function.

那么这些隐式转换序列呢?

让我们跳到§13.3.3.1[over.best.ics] / 3,看看隐式转换序列是什么:

A well-formed implicit conversion sequence is one of the following forms:
— a standard conversion sequence (13.3.3.1.1),
— a user-defined conversion sequence (13.3.3.1.2), or
— an ellipsis conversion sequence (13.3.3.1.3).

我们对标准转换序列感兴趣。让我们弹出标准转换序列(§13.3.3.1.1[over.ics.scs]):

1 Table 12 summarizes the conversions defined in Clause 4 and partitions them into four disjoint categories: Lvalue Transformation, Qualification Adjustment, Promotion, and Conversion. [ Note: These categories are orthogonal with respect to value category, cv-qualification, and data representation: the Lvalue Transformations do not change the cv-qualification or data representation of the type; the Qualification Adjustments do not change the value category or data representation of the type; and the Promotions and Conversions do not change the value category or cv-qualification of the type. — end note ]

2 [ Note: As described in Clause 4, a standard conversion sequence is either the Identity conversion by itself (that is, no conversion) or consists of one to three conversions from the other four categories.

重要的部分是/ 2。标准转换序列允许为单个标准转换。这些标准转换在下表12中列出,如下所示。请注意,您的指针转换和布尔转换都在其中。

Table of standard conversions and their categories and ranks

从这里,我们学到了一些重要的知识:指针转换和布尔转换具有相同的等级。请记住,当我们转到"对隐式转换序列进行排名"(第13.3.3.2节[over.ics.rank])时。

看/ 4,我们看到:

Standard conversion sequences are ordered by their ranks: an Exact Match is a better conversion than a Promotion, which is a better conversion than a Conversion. Two conversion sequences with the same rank are indistinguishable unless one of the following rules applies:

— A conversion that does not convert a pointer, a pointer to member, or std::nullptr_t to bool is
better than one that does.

我们以非常明确的陈述形式找到了答案。万岁!