`std::lock_guard<std::mutex>` 对象没有名称时的不同行为

Different behavior when `std::lock_guard<std::mutex>` object has no name

我正在学习 std::mutexstd::thread,我对以下 2 段代码的不同行为感到惊讶:

#include <iostream>
#include <mutex>
#include <thread>
using namespace std;

std::mutex mtx;

void foo(int k)
{
    std::lock_guard<std::mutex> lg{ mtx };
    for (int i = 0; i < 10; ++i)
        cout << "This is a test!" << i << endl;
    cout << "The test " << k << " has been finished." << endl;
}

int main()
{
    std::thread t1(foo, 1);
    std::thread t2(foo, 2);
    t1.join();
    t2.join();
    return 0;
}

输出是顺序的。但是如果我不命名变量 std::lock_guard<std::mutex>,输出是 unordered

void foo(int k)
{
    std::lock_guard<std::mutex> { mtx }; // just erase the name of variable
    for (int i = 0; i < 10; ++i)
        cout << "This is a test!" << i << endl;
    cout << "The test " << k << " has been finished." << endl;
}

在第二种情况下似乎std::lock_guard没有用,为什么?

这个声明

std::lock_guard<std::mutex> { mtx };

不会将创建的对象绑定到名称,它是一个临时变量,仅针对此特定语句存在。与此相反,具有名称并在堆栈上创建的变量一直存在到创建它的范围的末尾。

this CppCon talk (starting at 31:42) 中,演示者将创建未绑定到局部变量的临时 std::lock_guard 实例列为 Facebook 代码库中的常见错误。