统一初始化语法差异

Uniform initialization syntax difference

本文关键字:语法 初始化      更新时间:2023-10-16

A a{ A() };

,

A a( A{} );

避免最烦人的解析?什么时候我应该使用特定的一个?

这两种语法在大多数情况下是等效的,选择哪一种主要取决于个人喜好。如果您正在进行统一初始化,我建议这样做:

A a{ A{} };

否则,可以单独使用括号消除歧义:

A a((A())); // This can't be parsed as a function declaration

注意,有一种情况(我必须说很不可能),你的问题中显示的两种形式是不相等的。如果您的类A有一个接受initializer_list<A>的构造函数,那么当使用大括号时,该构造函数将优于复制构造函数:

#include <initializer_list>
#include <iostream>
struct A
{
    A() { }
    A(std::initializer_list<A> l) { std::cout << "init-list" << std::endl; }
    A(A const& a) { std::cout << "copy-ctor" << std::endl; }
};
int main()
{
    A a(A{}); // Prints "copy-ctor" (or nothing, if copy elision is performed)
    A b{A()}; // Prints "init-list"
}

上述差异在实例中显示。

在大多数情况下它们是等价的,但是A a{ A() };将更喜欢std::initializer_list构造函数(如果存在的话),而A a( A{} );将更喜欢移动/复制构造函数。

当构造结束调用移动/复制构造函数时,可以省略新对象的构造,但这对于std::initializer_list构造函数是不可能的。

这两种语法都不会被解析为函数声明,因此都避免了最麻烦的解析。

#include <iostream>
#include <initializer_list>
struct A {
    A() {
        std::cout << "A()n";
    }
    A(A&&) {
        std::cout << "A(A&&)n";
    }
    A(std::initializer_list<A>) {
        std::cout << "A(std::initializer_list<A>)n";
    }
};
int main()
{
    {A a{ A() };} // Prints "A()n" "A(std::initializer_list<A>)n"
    {A a( A{} );} // Prints "A()n" and *possibly*
                  // (depending on copy elision) "A(A&&)n"
}