为什么指针到int转换为void *但是指向函数的指针转换为bool? [英] Why does pointer to int convert to void* but pointer to function convert to bool?

查看:179
本文介绍了为什么指针到int转换为void *但是指向函数的指针转换为bool?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

C ++草案标准(N3337)有关于指针转换的以下内容:




2指向 cv T 的类型的右值c $ c> T 是一个对象类型,可以转换为指向 cv 类型的右值 void 。将指向 cv T 的指针转换为指向 cv <$ c $的指针的结果c> void 指向类型 T 的对象所在的存储位置的开始,就像该对象是最导出的对象 T (即不是基类子对象)。




< 1算术,枚举,指针或指向成员类型的指针的右值可以转换为 bool 类型的右值。零值,空指针值或空成员指针值将转换为false;任何其他值都转换为true


基于上述,完全可以将函数指针或指针转换为 void * 以及 bool p>

然而,考虑到两者的选择,指针应该转换成哪一个?



指向一个函数的指针转换为 bool 和指向 int 的指针转换为 void *



计划:

  #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输出:

 
在foo(bool)
在foo(void *)


解决方案


基于上述,将函数指针或指针转换为 int void * 以及 bool


引用说明,指向对象的指针可以转换为 cv void * 。函数不是对象,并且不允许转换为 cv void * ,只保留 bool







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


应该转换为 const void * over 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总结了转换,并将其分为四个不相交的类别:左值转换,资格调整,促销和转换。 [注意:这些类别相对于值类别,cv限定和数据表示是正交的:L值变换不改变类型的cv限定或数据表示;资格调整不会更改类型的值类别或数据表示;并且促销和转化不会更改类型的值类别或cv-qualification。 - end note]



2 [注意:如第4条所述,标准转换序列是身份转换本身(即没有转换)


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





从这里,我们学到了一些重要的:指针转换和布尔转换具有相同的排名。记住,在我们前往排序隐式转换序列(§13.3.3.2[over.ics.rank])。



看看/ 4,我们看到:


标准转换序列按其排名顺序排列:完全匹配是一种比促销更好的转化,这是比转化更好的转化。除非以下规则之一适用,否则具有相同排名的两个转换序列是不可区分的:



- 不转换指针,指向成员的指针或std的转换: :nullptr_t到bool是
比一个更好。


我们发现我们的答案是非常显式语句。 Hooray!


The C++ Draft Standard (N3337) has the following about conversion of pointers:

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

and

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

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.

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

And then, why does a pointer to a function convert to a bool and a pointer to an int convert to a void*?

Program:

#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;
}

Output, using g++ 4.7.3:

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.

The quotation states that a pointer to an object can be converted to cv void *. Functions are not objects, and this disqualifies the conversion to cv void *, leaving only bool.


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

It should convert to const void * over bool. Why? Well, prepare for a journey that starts in Overload Resolution (§13.3 [over.match]/2). Emphasis mine, of course.

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.

So what about these implicit conversion sequences?

Let's jump over to §13.3.3.1 [over.best.ics]/3 and see just what an implicit conversion sequence is:

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

We're interested in standard conversions sequences. Let's pop over to Standard Conversion Sequences (§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.

The important part is in /2. A standard conversion sequence is allowed to be a single standard conversion. These standard conversions are listed in Table 12, shown below. Notice that both your Pointer Conversions and Boolean Conversions are in there.

From here, we learn something important: Pointer conversions and boolean conversions have the same rank. Remember that as we head to Ranking Implicit Conversion Sequences (§13.3.3.2 [over.ics.rank]).

Looking at /4, we see:

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.

We've found our answer in the form of a very explicit statement. Hooray!

这篇关于为什么指针到int转换为void *但是指向函数的指针转换为bool?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆