【发布时间】:2011-07-28 06:02:32
【问题描述】:
以下表达式通常用于演示 undefined 未指定的行为:
f() + g()
如果f() 和g() 都对某些共享对象有副作用,则行为是undefined 未指定,因为执行顺序未知。 f() 可以在 g() 之前评估,反之亦然。
现在我想知道当你在一个对象上链接成员函数时会发生什么。假设我有一个类的实例,该实例名为obj,它有两个成员函数foo() 和bar(),它们都修改了对象。这些函数的执行顺序不可交换。在另一个之前调用它们的效果与反过来调用它们的效果不同。这两种方法都返回对*this 的引用,因此它们可以像这样被链接起来:
obj.foo().bar()
但这是未指定的行为吗?我在标准中找不到任何东西(诚然只是浏览)可以区分这个表达式和我在帖子顶部给出的表达式。两个函数调用都是完整表达式的子表达式,因此它们的执行顺序是未指定的。但肯定foo() 必须首先被评估,以便bar() 知道要修改哪个对象。
也许我遗漏了一些明显的东西,但我看不到序列点的创建位置。
【问题讨论】:
-
行为肯定是被定义的。但我无法指出标准的相关部分。
-
正是我遇到的问题。我知道肯定必须定义它,但我就是看不到它。我只想关门!
-
函数调用的结尾是一个序列点(1.9.17)。由于
foo()的结果是bar()的参数(隐含的this-指针),所以顺序明确。 -
@Space_C0wb0y 太棒了!而已!我没有将 foo() 的结果实际上是 bar() 的参数这一事实联系起来。愿意将其发布为答案以便我接受吗?
-
@Space_C0wb0y 可以说隐含对象参数和隐含对象参数在重载决议之外不存在。这些构造仅存在于成员函数在重载决议期间与非成员函数可比较的情况下。第 13 节说“出于重载决议的目的,静态和非静态成员函数都具有隐式对象参数,但构造函数没有。”。这就是为什么我试图从规范的其他保证中推导出
obj.foo().bar()的行为。 (强调我的)。
标签: c++ method-chaining sequence-points