为什么指向 int 的指针会转换为 void* 而指向函数的指针会转换为 bool?

2024-04-28

C++ 标准草案 (N3337) 对指针转换有以下规定:

4.10 指针转换

2 “指向的指针”类型的右值cv T,“ 在哪里T是一个对象类型,可以转换为“指向的指针”类型的右值cv void”。将“指针转换为cv T” 到“指向cv void” 指向类型对象的存储位置的开始T驻留,就好像该对象是类型的最派生对象 (1.8)T(即不是基类子对象)。

and

4.12 布尔转换

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

综上所述,将函数指针或指针转换为指针是完全可以的int to a void*bool.

然而,如果可以选择两者,指针应该转换为哪一个呢?

然后,为什么指向函数的指针会转换为bool和一个指向int转换为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;
}

输出,使用 g++ 4.7.3:



In foo(bool)
In foo(void*)
  

综上所述,将函数指针或指针转换为指针是完全可以的int to a void*bool.

引用指出,一个指向object可以转换为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 总结了第 4 条中定义的转换,并将它们分为四个不相交的类别:左值转换、资格调整、升级和转换。 [注意:这些类别相对于值类别、cv 限定和数据表示是正交的:左值变换不会更改类型的 cv 限定或数据表示;资格调整不会改变类型的值类别或数据表示;并且促销和转换不会更改类型的价值类别或简历资格。 ——尾注]

2 [ 注意:如第 4 条所述,标准转换序列要么是 Identity 转换本身(即无转换),要么由来自其他四个类别的一到三个转换组成。

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

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

查看 /4,我们看到:

标准转换序列按其等级排序:精确匹配是比促销更好的转换,促销是比转换更好的转换。除非满足以下规则之一,否则具有相同秩的两个转换序列是无法区分的:

— 不将指针、指向成员的指针或 std::nullptr_t 转换为 bool 的转换是 比这样做的更好。

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么指向 int 的指针会转换为 void* 而指向函数的指针会转换为 bool? 的相关文章

  • Visual Studios 2015 中的“恢复 NuGet 包”没有执行任何操作

    我将解决方案从 SVN 拉入 Visual Studios 2015 代码中的一些 使用 引用出现错误 因此我尝试在右键单击 解决方案 中的解决方案时运行 恢复 NuGet 包 选项探索者 这没有任何作用 我必须手动进入 nuget 管理器
  • C# 中类似图的实现

    所以我有一个对象 我们称之为 Head 它有一个对象列表 C C1 C2 C3 T T1 T2 和 M M1 M2 并且所有这些都是相互关联的 例如 Head gt C1 C2 C3 T1 T2 M1 M2 T1 gt C1 C2 T2 g
  • 如何使用c#从数据桶中获取所有文档?

    如何获取数据桶中的所有文档 我尝试过一个示例 但我只能获得一个特定的文档 这是我的代码 CouchbaseClient oclient oclient new CouchbaseClient vwspace data bucket name
  • 预编译头和 Visual Studio

    有没有办法设置 Visual Studio 解决方案参数 以便它只创建预编译头而不构建整个解决方案 具体来说 它是一个巨大的 C 解决方案 本身有许多项目 谢谢 仅选择 pch 创建者源文件 通常是 stdafx cpp 然后编译该文件 C
  • 如何从不同的线程访问控件?

    如何从创建控件的线程以外的线程访问控件 避免跨线程错误 这是我的示例代码 private void Form1 Load object sender EventArgs e Thread t new Thread foo t Start p
  • 无法将参数从 `const char *` 转换为 `char *`

    鉴于此代码 void group build int size std string ips Build the LL after receiving the member list from bootstrap head new memb
  • 为什么像 BindingList 或 ObservableCollection 这样的类不是线程安全的?

    我一次又一次发现自己必须编写 BindingList 和 ObservableCollection 的线程安全版本 因为当绑定到 UI 时 这些控件无法从多个线程更改 我想理解的是why情况就是这样 这是设计错误还是故意的 问题是设计一个线
  • 在 .NET Core 中从 HttpResponseMessage 转换为 IActionResult

    我正在将之前在 NET Framework 中编写的一些代码移植到 NET Core 我有这样的事情 HttpResponseMessage result await client SendAync request if result St
  • 如何使用 CUDA/Thrust 对两个数组/向量根据其中一个数组中的值进行排序

    这是一个关于编程的概念问题 总而言之 我有两个数组 向量 我需要对一个数组 向量进行排序 并将更改传播到另一个数组 向量中 这样 如果我对 arrayOne 进行排序 则对于排序中的每个交换 arrayTwo 也会发生同样的情况 现在 我知
  • 如何在 Visual Basic DLL 和 C++ DLL 之间创建隔离/免注册 COM?

    我必须在 C DLL 中使用 VB COM DLL 我弄清楚了如何从 C DLL 访问 VB COM DLL 并且它可以工作 现在我遇到了一个问题 我必须使用隔离的 COM 免注册 COM 因为我无法在必须使用它的每台 PC 上注册 DLL
  • 如何调试.NET Windows Service OnStart方法?

    我用 NET 编写的代码仅在作为 Windows 服务安装时才会失败 该故障甚至不允许服务启动 我不知道如何进入 OnStart 方法 如何 调试 Windows 服务应用程序 http msdn microsoft com en us l
  • std::make_pair 与浮点数组(float2,无符号整数)

    我有一个用 float2 unsigned int 对模板化的向量 例如 std vector
  • 模板与非模板类,跨编译器的不同行为

    我在一些应用程序中使用编译时计数器 它确实很有用 昨天我想用 gcc 编译一个程序 我之前使用的是 msvc 并且计数器的行为在模板类中发生了变化 它在模板类中不再工作 过于简化的代码 Maximum value the counter c
  • ASP.NET MVC 动作过滤器

    有谁知道即使在 CATCH 块中 ActionFilterAttribute 类的 OnResultExecuted 方法是否也会执行 ie CookiesActions public ActionResult Login Usuarios
  • 如何禁用基于 ValidationRule 类的按钮?

    如何禁用基于 ValidationRule 类的 WPF 按钮 下面的代码可以很好地突出显示 TextBox
  • 应在堆栈上分配的最大数量

    我一直在寻找堆栈溢出有关应在堆栈上分配的最大内存量的指南 我看到了堆栈与堆分配的最佳实践 但没有关于应该在堆栈上分配多少以及应该在堆上分配多少的指南 有什么想法 数字可以作为指导吗 什么时候应该在堆栈上分配 什么时候应该在堆上分配 多少才算
  • C - 获取外部IP地址

    我需要通过 C C 调用获取我的公共 IP 地址 我知道作为替代方案 我可以从 http whatismyip akamai com 等外部链接获取 我写了一个示例来获取外部IP地址 但我的程序没有返回外部 IP 地址 我正在获取内部 IP
  • 为什么 C++ 标准没有将 sizeof(bool) 定义为 1?

    Size of char signed char and unsigned char由 C 标准本身定义为 1 个字节 我想知道为什么它没有定义sizeof bool also C 03 标准 5 3 3 1 说 sizeof char s
  • Unity - 在生成时获取随机颜色

    我有一个小问题 我想在我的场景中生成四边形 它们都应该有红色或绿色作为材质 但 Random Range 函数只能是 int 我该如何解决它 void SpawningSquadsRnd rndColor 0 Color red rndCo
  • 如何根据当前日期时间发现财政年度?

    我需要基于当前或今天的日期时间的财政年度 假设我们认为今天的日期是10 April 2011 那么我需要输出为Financial Year 2012在某些情况下 我需要以短格式显示相同的输出FY12 我想以两种方式显示 在我们的要求中 考虑

随机推荐