C++ 函数本地静态函数对象';s由lambda初始化,是否线程安全?

C++ 函数本地静态函数对象';s由lambda初始化,是否线程安全?,c++,static,lambda,c++11,thread-safety,C++,Static,Lambda,C++11,Thread Safety,以下函数是线程安全的吗?如果它不是线程安全的,那么在使funImpl非静态时真的有开销吗?或者编译器实际上内联了该函数对象,并跳过了创建函数对象 int myfun(std::array<int, 10> values) { static const auto funImpl = [&]() -> int { int sum = 0; for (int i = 0; i < 10; ++i) {

以下函数是线程安全的吗?如果它不是线程安全的,那么在使funImpl非静态时真的有开销吗?或者编译器实际上内联了该函数对象,并跳过了创建函数对象

int myfun(std::array<int, 10> values)
{
    static const auto funImpl = [&]() -> int
    {
        int sum = 0;

        for (int i = 0; i < 10; ++i)
        {
            sum += values[i];
        }
        return sum;
    };

    return funImpl();
}
int-myfun(std::数组值)
{
静态常量自动函数impl=[&]()->int
{
整数和=0;
对于(int i=0;i<10;++i)
{
总和+=数值[i];
}
回报金额;
};
return funImpl();
}
编辑: 我从以下位置编辑了函数签名:

int myfun(const std::array<int, 10>& values)
int-myfun(常量std::数组和值)
致:

int-myfun(std::数组值)

因此,很明显,我不是在问值的线程安全性,而是在问函数局部静态变量funImpl的线程安全性。

它不仅不是线程安全的,也不是你想要的

通过将lambda定义为静态,它捕获(通过引用)第一次调用时传递的数组。进一步的调用将继续引用原始数组,而不管传入哪个数组

当第一个数组超出范围时,进一步的调用将调用UB,因为它现在有一个悬空引用

编辑:一个例子


注意,即使您是通过值捕获的,您仍然会遇到问题,因为它仍然只会捕获您第一次调用函数的时间。您不会有悬空的指针,但它仍然只会在第一次初始化副本。

是否有理由使用该指针而不是
std::acculate
?显然没有理由使用该代码。它的存在只是为了让我能够问我的问题。@JerryCoffin如果
std::acculate
使用迭代器,那么在某些实现中,这个版本可能比
std::acculate
更快吗?假设10只是为了这个例子的目的,可以是更大的东西。@MattPhillips:我想它可能会更快,但考虑到它做的不对,我怀疑它是否重要。谢谢,我不敢相信我不知道这一点。
int myfun(std::array<int, 10> values)