- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
下面的示例代码打印来自 lambda 函数的值,该函数简单地递增并返回静态局部计数器变量的值。
它打印0,1
和 2,3
正如预期的那样,gcc 和 C++17 的 clang。但在 Visual Studio Community 2017 15.9.3 中没有 /std:c++17
设置 - 它打印 0,0
和 2,3
相反。
#include <iostream>
int main() {
auto f = [] {
static int i = 0;
return i++;
};
const int v1 = f(); // Expect v1 = 0
const int v2 = f(); // Expect v2 = 1
// Prints the wrong values (MSVC 15.9.3 with /std:c++17)
std::cout << v1 << "," << v2 << std::endl; // Expect "0,1", prints "0,0"
// Prints the right values (or ought to with C++17 sequencing, anyway)
std::cout << f() << "," << f() << std::endl; // Expect "2,3", prints "2,3"
return 0;
}
奇怪的输出(在 x86 调试版本中)
0,0
2,3
它看起来像一个编译器错误(因此我们提交了报告):https://developercommunity.visualstudio.com/content/problem/347419/unexpected-return-from-lambda-with-static-local-va.html
生成的程序以何种方式出错,以至于它错误地打印了0
对于v1
和 v2
, 但正确打印 2, 3
在那之后?对编译器错误是什么有任何有根据的猜测吗?
作为解决方法,我改用捕获:
auto f = [i = 0]() mutable {
return i++;
};
更新 - 作为旁注,上述示例的输出在 x86 版本构建中再次不同:
0,1
3,2
MSVC 还存在另一个问题,其中 std::cout
的 <<
尽管 /std:c++17
,运算符并未从左到右排序正在设置,我推测这会导致 3,2
至少在这里输出。
最佳答案
MSVC 干净地编译了以下内容:
constexpr int foo() {
static int i = 0;
return i++;
}
static_assert(foo() == foo()); // oh no
这不符合标准。
因此,自 C++17 起,lambda 隐式为 constexpr
(如果可以的话)。 MSVC 错误地认为 lambda 是 constexpr
,因此将 f()
折叠成 v2
的常量(它从 v1
)。当你直接输出它时它不会这样做,因为它显然不会像 gcc 那样急切地评估 constexpr
东西(或使用我们不知道的其他一些启发式)。
关于c++ - lambda 如何在 MSVC2017 15.9.3 with/std :c++17? 中使用静态本地错误返回值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53660576/
我是一名优秀的程序员,十分优秀!