- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
在 C++17 evaluation order guarantees (P0145) 中投票的含义是什么?在典型的 C++ 代码上?
它对以下内容有何改变?
i = 1;
f(i++, i)
和
std::cout << f() << f() << f();
或
f(g(), h(), j());
最佳答案
一些常见情况下,评估顺序迄今尚未未指定,但在 C++17
中已指定且有效。一些未定义的行为现在是未指定的。
i = 1;
f(i++, i)
未定义,但现在未指定。具体而言,未指定的是 f
的每个参数相对于其他参数的评估顺序。 i++
可能在 i
之前计算,反之亦然。事实上,尽管在同一个编译器下,它可能会以不同的顺序评估第二个调用。
但是,在执行任何其他参数之前,要求完整执行每个参数的评估,并带有所有副作用。因此,您可能会得到 f(1, 1)
(第二个参数首先计算)或 f(1, 2)
(第一个参数首先计算)。但是你永远不会得到 f(2, 2)
或任何其他类似的东西。
std::cout << f() << f() << f();
未指定,但它将与运算符优先级兼容,以便 f
的第一个评估将在流中排在第一位(下面的示例)。
f(g(), h(), j());
仍然具有未指定的 g、h 和 j 的评估顺序。请注意,对于 getf()(g(),h(),j())
,规则规定 getf()
将在 g 之前计算, h, j
.
另请注意提案文本中的以下示例:
std::string s = "but I have heard it works even if you don't believe in it"
s.replace(0, 4, "").replace(s.find("even"), 4, "only")
.replace(s.find(" don't"), 6, "");
该示例来自 The C++ Programming Language,第 4 版,Stroustrup,过去是未指定的行为,但在 C++17 中它将按预期工作。可恢复函数 (.then( . . . )
) 也存在类似问题。
作为另一个示例,请考虑以下内容:
#include <iostream>
#include <string>
#include <vector>
#include <cassert>
struct Speaker{
int i =0;
Speaker(std::vector<std::string> words) :words(words) {}
std::vector<std::string> words;
std::string operator()(){
assert(words.size()>0);
if(i==words.size()) i=0;
// Pre-C++17 version:
auto word = words[i] + (i+1==words.size()?"\n":",");
++i;
return word;
// Still not possible with C++17:
// return words[i++] + (i==words.size()?"\n":",");
}
};
int main() {
auto spk = Speaker{{"All", "Work", "and", "no", "play"}};
std::cout << spk() << spk() << spk() << spk() << spk() ;
}
在 C++14 之前,我们可能(并且将会)得到如下结果
play
no,and,Work,All,
代替
All,work,and,no,play
请注意,上面的效果与
相同(((((std::cout << spk()) << spk()) << spk()) << spk()) << spk()) ;
但是,在 C++17 之前,仍然不能保证第一个调用首先进入流。
引用文献:来自 the accepted proposal :
Postfix expressions are evaluated from left to right. This includesfunctions calls and member selection expressions.
Assignment expressions are evaluated from right to left. Thisincludes compound assignments.
Operands to shift operators are evaluated from left to right. Insummary, the following expressions are evaluated in the order a, thenb, then c, then d:
- a.b
- a->b
- a->*b
- a(b1, b2, b3)
- b @= a
- a[b]
- a << b
- a >> b
Furthermore, we suggest the following additional rule: the order ofevaluation of an expression involving an overloaded operator isdetermined by the order associated with the corresponding built-inoperator, not the rules for function calls.
编辑说明:我原来的答案误解了a(b1, b2, b3)
。 b1
、b2
、b3
的顺序仍未指定。 (感谢@KABoissonneault,所有评论者。)
然而,(正如@Yakk 指出的那样)这很重要:即使 b1
、b2
、b3
是非平凡的表达式,在开始评估其他参数之前,它们中的每一个都被完全评估并绑定(bind)到相应的函数参数。标准是这样规定的:
§5.2.2 - Function call 5.2.2.4:
. . .The postfix-expression is sequenced before each expression in theexpression-list and any default argument. Every value computation andside effect associated with the initialization of a parameter, and theinitialization itself, is sequenced before every value computation andside effect associated with the initialization of any subsequentparameter.
但是,the GitHub draft 中缺少其中一个新句子:
Every value computation and side effect associated with theinitialization of a parameter, and the initialization itself, issequenced before every value computation and side effect associatedwith the initialization of any subsequent parameter.
例子是。它解决了一个存在数十年之久的问题 ( as explained by Herb Sutter ),异常安全,比如
f(std::unique_ptr<A> a, std::unique_ptr<B> b);
f(get_raw_a(), get_raw_a());
如果其中一个调用 get_raw_a()
在另一个调用之前抛出,将会泄漏原始指针与其智能指针参数相关联。
正如 T.C. 所指出的,该示例存在缺陷,因为原始指针的 unique_ptr 构造是显式的,因此无法编译。*
还要注意这个经典question (标记为 C,而不是 C++):
int x=0;
x++ + ++x;
仍未定义。
关于c++ - C++17 引入的求值顺序保证是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46471806/
在开始之前,我想指出的是,我已经通过Google进行了一次诚实而真实的搜索,涉及范围很广,无法找到。 我需要(对于我正在开发的项目)所有Delphi(从2007年到最新发布的版本,我不再支持任何早于2
我正在使用 RPM 将 Liquibase 数据库迁移添加到我们当前的产品部署中,并正在寻找一些有关如何实现我的预期目标的建议/技巧。 最好,RPM 能够安装在全新且 Shiny 的开发人员环境以及现
我目前正在使用一本书学习 UITableViewCell。为了在滚动时重用单元格,作者要求修改原始代码以包含一个if()。检查特定重用标识符的单元格是否存在的语句。但是,在添加 if() 之后语句,X
在 C++ 中引入 protected 访问说明符背后的基本原理是什么。举个例子会有帮助。 最佳答案 对于这类问题,我推荐 Bjarne Stroustrup 的The Design And Evol
我正在尝试使用模板参数中给定的维度和类型创建一个可重用的矩阵类。结构本身就是: template struct Matrix { T elements[N* M]; }; 当我尝试实现矩阵乘
我有一个简单的查询: $query1="SELECT * FROM wp_users WHERE now() < (last_login + INTERVAL 6 month)"; $resu
在 Ioke doc 中,ISpec 测试包含在文档中,参见 ioke.org/dok/index.html 这如何用 Ruby 的 RSpec 和 RDoc(或 SDoc)来完成?我找不到任何命令行
在客户端/服务器通信中,我看到来自客户端的 TCP ZeroWindow。 在这种情况之后预期的场景是什么(设置和发送什么标志)? 以下是我可能得到的日志。在这种情况下,服务器发送 RST 数据包来终
来自wikipedia关于 Lambda 函数和表达式的文章: users will often wish to define predicate functions near the place w
我有一个由父 POM 和几个子模块组成的 Maven 项目。它在 Intellij 中编译和运行良好(我假设它使用 javac 而不是 Maven)。 当我运行 maven clean install
所以我刚开始使用 d3.js,但我一直收到 JavaScript 错误,我不知道为什么。我刚刚用 svg 创建了三个圆圈,想用 d3 选择它们。这是我的代码:
Objective C 引入了一种称为 ARC 的技术,以将开发人员从内存管理的负担中解放出来。听起来不错,如果g++也有这个功能,我想C++开发者会很高兴的。 ARC allows you to p
在 package.json 添加 "font-awesome": "^4.7.0" 执行 npm install 在 main.js 引入
为什么 WSDL 引入 wsdl:message?和消息部分? 与在操作参数(输入、输出、故障)中直接使用 XSD 相比,他们可以带来什么优势? 它们(带有 wsdl 消息部分的 wsdl 消息)如何
I already read doc here : https://github.com/laravel/framework/pull/25997 我想知道的是使用 withCount()我们只是加载
我已经为此苦苦挣扎了一段时间,但不太明白发生了什么。我有一个包含 Sides(通常是 2 个)的 Card 实体 - 并且 Cards 和 Sides 都有一个 Stage。我正在使用 EF Code
下面的 swiftUI 代码在 iOS13 上运行良好,但是在使用 iOS14 进行测试时,我在尝试显示模式表时遇到了由强制解包选项引起的 fatal error 。据我所知,工作表不应该尝试为 se
出于个人原因,我需要记忆一下 jsp 上的一些事情 :) 我有一个简单的登录页面: Login First name:
据我了解,PYTHONCASEOK 选项允许通过不区分大小写的匹配来导入模块。但是,由于 python 中的几乎所有内容都区分大小写,为什么它必须启用此选项以实现更惰性的写入。 还有什么介绍的理由吗?
全新的早午餐(和 bower )。我通过 bower 安装了 Bootstrap,我有以下早午餐配置文件: exports.config = # See http://brunch.io/#doc
我是一名优秀的程序员,十分优秀!