C++ 中未评估的上下文是什么?

2023-12-23

我经常想到的一个例子是:

sizeof表达式,它不计算表达式,而是通过静态类型确定大小。例如 :

int func();
sizeof(func());

这是我的思维极限,所以如果还有其他未评估的上下文,那么它们是什么呢?


幸运的是,该标准有一个方便的列表(§ 5 [expr] ¶ 8):

在某些情况下,未评估的操作数出现(5.2.8、5.3.3、5.3.7、7.1.6.2)。未计算的操作数不会被计算。未计算的操作数被视为完整表达式。

让我们详细看看这些。

我将在我的示例中使用以下声明。声明的函数永远不会在任何地方定义,因此如果对它们的调用出现在评价的在上下文中,程序格式不正确,我们将收到链接时错误。然而,在未评估的上下文中调用它们是可以的。

int foo();  // never defined anywhere

struct widget
{
  virtual ~widget();
  static widget& get_instance();  // never defined anywhere
};

typeid

§ 5.2.8 [expr.typeid] ¶ 3:

When typeid应用于多态类类型的左值以外的表达式,结果指的是std::type_info表示表达式的静态类型的对象。左值到右值 (4.1)、数组到指针 (4.2) 和函数到指针 (4.3) 转换不适用于表达式。如果表达式的类型是类类型,则该类应是完全定义的。该表达式是未计算的操作数 (第 5 条)。

请注意多态类的强调例外(aclass至少有一个virtual成员)。

因此,这是可以的

typeid( foo() )

并产生一个std::type_info对象为int而这

typeid( widget::get_instance() )

不是并且可能会产生链接时错误。它必须评估操作数,因为动态类型是通过查找来确定的vptr在运行时。

我发现很令人困惑的是,操作数的静态类型是否是多态的这一事实以如此戏剧性但微妙的方式改变了运算符的语义。

sizeof

§ 5.3.3 [expr.sizeof] ¶ 1:

The sizeof运算符产生其操作数的对象表示形式中的字节数。操作数是一个表达式,它是一个未计算的操作数(第 5 条),或带括号的type-id. The sizeof运算符不得应用于具有函数或不完整类型的表达式、在声明其所有枚举器之前其基础类型未固定的枚举类型、此类类型的括号名称或指定位的泛左值。场地。

下列

sizeof( foo() )

完全没问题,相当于sizeof(int).

sizeof( widget::get_instance() )

被允许。但请注意,它相当于sizeof(widget)因此对于多态可能不是很有用return type.

noexcept

§ 5.3.7 [expr.unary.noexcept] ¶ 1:

The noexcept运算符确定是否评估它的操作数,是一个未计算的操作数(第 5 条),可以抛出异常(15.1)。

表达方式

noexcept( foo() )

是有效的并且评估为false.

这是一个更现实的例子,也是有效的。

void bar() noexcept(noexcept( widget::get_instance() ));

注意,只有内部noexcept是运算符,而外部是说明符。

decltype

§ 7.1.6.2 [dcl.type.simple] ¶ 4.4:

的操作数为decltype说明符是一个未计算的操作数(第 5 条)。

该声明

decltype( foo() ) n = 42;

声明一个变量n类型的int并用值 42 对其进行初始化。

auto baz() -> decltype( widget::get_instance() );

声明一个函数baz不需要任何参数并且returns a widget&.

这就是全部(从 C++14 开始)。

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

C++ 中未评估的上下文是什么? 的相关文章

  • 代码块 power 函数在 c 中不起作用

    我正在使用代码块来学习c 我的代码是 include
  • 宏可以按参数数量重载吗?

    如何this https stackoverflow com q 9183993 153285工作 如何实现 C99 C 11 可变参数宏以仅根据为其提供多少个参数来扩展到不同的事物 编辑 请参阅末尾以获得现成的解决方案 要获得重载的宏 首
  • 在 C# 中调用事件处理程序

    我一直在尝试学习如何在 C 中使用事件处理程序 但我无法弄清楚 handler this e 在以下代码中的作用 public event EventHandler ThresholdReached protected virtual vo
  • C++:将模板参数的模板类型成员添加为好友的正确语法?

    我有一个带有模板类型参数 tTRAIT 的类 我想加一个模板为好友type member aliastTRAIT 但我无法弄清楚语法 这可能吗 template
  • 如何使用boost库读取和写入.ini文件[重复]

    这个问题在这里已经有答案了 如何使用boost库读取和写入 或修改 ini文件 With Boost PropertyTree您可以读取并更新树 然后写入文件 请参阅load and save功能 看一下如何访问属性树中的数据 http w
  • 在 C++ 中使用表达式模板进行符号微分

    如何在 C 中使用表达式模板实现符号微分 一般来说 您需要一种表示符号的方法 即编码的表达式模板 例如3 x x 42 以及一个可以计算导数的元函数 希望您对 C 中的元编程足够熟悉 知道这意味着什么和需要什么 但可以给您一个想法 This
  • Visual Studio Code 调试默认 ASP.NET Core MVC WebApp:不起作用

    我正在使用 Manjaro linux 并尝试调试默认的 ASP NET Core MVC 项目 但调试停止 没有任何错误 我创建了该项目 dotnet new mvc in a Meow文件夹 没什么特别的 然后添加了新的配置 NET C
  • 使用 QGraphicsScene 实现流畅的动画

    我希望我的问题并不总是同样的问题 我有一个 QGraphicsScene 它的项目是一些 QGraphicsPixmap 我用一个计时器来移动它们 每秒 SetX 10 我设置 10是因为窗口大100 使用这个解决方案我的动画不流畅 我想我
  • 只读有运行时开销吗?

    出于某种原因 我一直认为readonly字段有与其相关的开销 我认为这是 CLR 跟踪是否存在readonly字段是否已初始化 这里的开销是一些额外的内存使用量 用于跟踪状态以及分配值时的检查 也许我这么认为是因为我不知道readonly字
  • 带有自定义鉴别器的 EntityFramework Code First 继承

    我正在尝试在 EntityFramework Code First 中映射以下继承 public class Member public string ProjectName get set public string AssemblyNa
  • 数组与映射的性能

    我必须循环一个大数组中的元素子集 其中每个元素都指向另一个元素 问题来自于检测大图中的连接组件 我的算法如下 1 考虑第一个元素 2 将下一个元素视为前一个元素所指向的元素 3 循环直到没有发现新元素 4 考虑1 3中尚未考虑的下一个元素
  • 非静态类中的静态方法和静态类中的静态方法有什么区别?

    我有两个班级A级和B级 static class ClassA static string SomeMethod return I am a Static Method class ClassB static string SomeMeth
  • EWS - 给予预约,获取预约的所有者副本

    在 EWS 中进行预约后 是否可以获得所有者的副本 例如 如果我登录为user1 我有user1创建的约会的副本user2 我有冒充权 我要编辑user2预约的副本 我怎样才能获得user2 s copy 您可以使用 PidLidClean
  • 从 exit() 和 fork() 返回的结果奇怪地发生了位移

    我有一个 C 代码 有时会自行分叉 每个分叉都会执行一些操作 然后返回一个错误代码 目前 每个子进程返回其 ID 0 n void other int numero exit numero int main for int i 0 i lt
  • C# Julian 日期解析器

    我在电子表格中有一个单元格 它是 Excel 中的日期对象 但当它来自 C1 的 xls 类时 它会变成双精度型 类似于 2009 年 1 月 7 日的 39820 0 我读到这是儒略日期格式 有人可以告诉我如何在 C 中将其解析回 Dat
  • 字符串 c 的二叉树

    我正在尝试实现一个能够在 c 中保存字符串的二叉树 在让代码适用于整数之后 我尝试稍微修改它以处理字符数组 现在我似乎完全破解了代码 但不知道如何破解 任何帮助表示赞赏 include
  • 如何在给定点停止线程?

    我试图停止一些线程 阅读一些有关优雅地执行此操作的正确方法的内容 但我一定做错了什么 因为它根本不起作用 起初我尝试不使用lock with IsRunning不稳定 然后尝试使用锁 这是我所拥有的 private volatile boo
  • 扔掉挥发物安全吗?

    大多数时候 我都是这样做的 class a public a i 100 OK delete int j Compiler happy But is it safe The following code will lead compilat
  • 如何在用户空间程序中使用内核 libcrc32c (或相同的函数)?

    我想在我自己的用户空间程序中进行一些 CRC 检查 我发现内核加密库已经在系统中 并且支持 SSE4 2 我尝试直接 include
  • 类模板的 C++ 静态成员 - 链接器警告“多重定义”[重复]

    这个问题在这里已经有答案了 假设出于某种原因 我想要一个类模板 MyTemp 和一些静态数据成员 smDummyVar Mytemp h ifndef MY TEMP H define MY TEMP H template

随机推荐