C++ 如果仅在lambda中使用,则在发布版本中未初始化局部静态变量

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()

请参阅下面的代码。正确的输出是“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(), 
    [](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)