【问题标题】:Is it legal to make a copy of initilizer_list in lambda?在 lambda 中复制 initilizer_list 是否合法?
【发布时间】:2026-01-14 03:40:02
【问题描述】:

请考虑这个简化的 C++14 程序:

#include <vector>
#include <iostream>

int main()
{
    auto l12 = {1,2};
    auto copy = []( auto v ) { return v; };
    std::vector<int> v{ copy( l12 ) };
    std::cout << v[0] << ' ' << v[1] << '\n';
}

GCC 在这里发出警告:

warning: returning local 'initializer_list' variable 'v' does not extend the lifetime of the underlying array [-Winit-list-lifetime]
    7 |     auto copy = []( auto v ) { return v; };

而其他编译器接受程序:https://gcc.godbolt.org/z/PPrsWxbfM

请问是程序格式错误还是 GCC 警告错误?

【问题讨论】:

  • 我认为std::initializer_list 是可复制的,这是一种错觉。编译器可能会对此发出警告,即使在更大的上下文中是可以的。
  • 话虽如此,“正确”的复制功能实际上有点不同:auto copy = [](auto const&amp; v){return v;};。对于这个,无论出于何种原因,编译器都不会抱怨。 gcc.godbolt.org/z/r1jY98rqr`

标签: c++ lambda c++14 initializer-list


【解决方案1】:

格式正确,没有UB。

auto l12 延长临时数组的生命周期,并使其保持活动状态直到main 结束。 auto v 和 lambda 的返回值不会扩展任何东西,但只要 l12 还活着就不是问题。


但总的来说,我不建议将std::initializer_list 用于函数参数以外的任何内容,因为存在棘手的生命周期扩展规则。

【讨论】: