C++11/17 中 std::atomic 的间接和直接初始化。有什么区别?

Indirect & Direct initialization of std::atomic in C++11/17. What are the differences?

当我看到这个 CPP Con 2017 网络研讨会时,Fedor Pikus 说:“它必须是直接初始化”

这是网络研讨会的 link

这些初始化方法有什么区别? (随后,为什么它必须是“直接”初始化?为什么“间接”初始化是“NOT”?)

// C++17 Compiler

#include <atomic>

class Example
{
    std::atomic<bool> m_b1 = false; // 1-h
    std::atomic<bool> m_b2{ false }; // 2-h

    static void doSomethng()
    {
        std::atomic<bool> b1 = false; // 1-f
        std::atomic<bool> b2{ false }; // 2-f
        std::atomic<bool> b3(false); // 3-f

        // Do something
    }
};

std::atomic不可复制或移动。

在 C++17 之前,copy-initialization std::atomic<int> x = 0; 将首先从 0 构造一个临时的 std::atomic<int> 然后 direct-initialize x从那个暂时的。如果没有移动或复制构造函数,这将失败,因此该行不会编译。

然而

std::atomic<int> x(0); 是 direct-initialization 并且只会构造 x 并向构造函数提供参数 0

从 C++17 开始就没有临时变量,x 将在任何情况下通过以 0 作为参数的构造函数调用直接初始化,因此 [=10= 没有问题] 是 non-movable。从这个意义上说,幻灯片现在是 out-dated.

尽管在这种情况下 copy-initialization 和 direct-initialization 的行为现在是相同的,但总体上两者之间仍然存在差异。特别是 direct-initialization 选择一个构造函数直接通过重载决议初始化变量,而 copy-initialization 试图找到一个隐式转换序列(可能通过转换具有不同重载决议规则的构造函数或转换函数)。此外,与 direct-initialization 相比,copy-initialization 不考虑标记为 explicit.

的构造函数

关于问题中的代码片段。 1-h1-f就是上面的copy-initialization。 3-f 就是上面的 direct-initialization。 2-h2-f 是 direct-list-initialization,在某些情况下与其他两者的行为不同,但在这里它与带括号的 direct-initialization 具有相同的效果。

解释一般初始化形式之间的所有差异需要一段时间。这是众所周知的 C++ 中最复杂的部分之一。