C++ 如果仅在lambda中使用,则在发布版本中未初始化局部静态变量
请参阅下面的代码。正确的输出是“102030”,但在发行版中构建它的“0”。为什么会发生这种情况C++ 如果仅在lambda中使用,则在发布版本中未初始化局部静态变量,c++,visual-studio-2015,lambda,visual-studio-2017,C++,Visual Studio 2015,Lambda,Visual Studio 2017,请参阅下面的代码。正确的输出是“102030”,但在发行版中构建它的“0”。为什么会发生这种情况 std::vector<int> inValues = {1, 2, 3}; std::vector<int> outValues(inValues.size()); static const int mag = 10; std::transform(inValues.cbegin(), inValues.cend(), outValues.begin()
std::vector<int> inValues = {1, 2, 3};
std::vector<int> outValues(inValues.size());
static const int mag = 10;
std::transform(inValues.cbegin(), inValues.cend(), outValues.begin(),
[](const auto value){
return value * mag;
});
for (const auto value: outValues)
std::cout << value << " ";
std::vector inValues={1,2,3};
std::vector outValues(inValues.size());
静态常数int mag=10;
std::transform(inValues.cbegin()、inValues.cend()、outValues.begin(),
[](常量自动值){
返回值*mag;
});
用于(常量自动值:outValues)
std::cout说到在lambdas中捕获变量,他说:
如果变量没有自动存储持续时间(即,它不是局部变量或它是静态的或线程局部的),则可以在不捕获的情况下使用该变量
您的变量是“静态局部”的,因此应该自动捕获
此外:
void fillVector(vector&v)
{
//局部静态变量。
静态int nextValue=1;
//在以下调用中显示的lambda表达式
//generate函数修改并使用本地静态
//变量nextValue。
生成(v.begin(),v.end(),[]{return nextValue++;});
//警告:这不是线程安全的,仅用于图示
}
尽管您的示例没有这样做,但这确实起到了预期的作用
这是一个bug。我可以报告它已在中清除。因此,尽管您可以随意将此报告为bug,但我建议您升级到Visual Studio 2017。如果您选择报告它,我建议您将错误报告链接到此处。有趣的是,编译时,mag
似乎设置为0;VisualStudio似乎没有意识到它实际上是在lambda表达式中使用的
您可以将mag
更改为仅为const int
;如果您在函数中定义了它,那么将int
定义为静态常量
与仅定义常量相比,几乎没有什么好处
否则,如果您坚持保持静态
限定符,您可以在定义后立即假装使用mag
,这样在编译时它的值就不会被优化:
static const int mag = 10;
(void)mag; // (pretend to use mag)
我以为你不需要捕捉静态变量?@frslm你说得对,很好。这是一个VisualStudio错误。找到复活节彩蛋需要+1。尝试使用叮当工具集构建,效果非常好。是的,这是一个bug。不,静态常量
是碰巧在这里使用的,无论如何这不是一个好的实践。在函数中提到mag
,只会掩盖编译器的错误。
static const int mag = 10;
(void)mag; // (pretend to use mag)