将初始化列表包装在括号内有什么影响?

What is the impact of wrapping an initializer list inside parenthesis?

将初始化列表包含在括号内有什么影响?它只是列表初始化的另一种形式还是仅在某些情况下有效?

例如,考虑 a:

struct A {
    A(float a, float b) {}
};

int main()
{
    A b(1.0f, 0.0f); // Direct initalization, finds ctor for (float, float)
    A c{1.0f, 0.0f}; // List initalization, finds a matching ctor

    A a({1.0f, 0.0f}); // Is this list initalization... which is expanded?
}

A a(something) 表示从 something 构建 a。因此,如果我们将 something 替换为 {1.0f, 0.0f},那么我们需要找到一个可以使用 {1.0f, 0.0f} 初始化参数的构造函数。我们仅有的构造函数是默认的复制和移动构造函数,它们分别采用 const A&A&&

所以,做

A a({1.0f, 0.0f});

实际上会创建一个临时文件 A,然后使用该临时文件初始化 a。在这种情况下,它将使用移动构造函数,因为对象是可移动的,并且在处理右值时移动构造函数优于复制构造函数。