10

することの違いは何ですか

A a{ A() };

と、

A a( A{} );

最も厄介な解析を避けるには?特定のものをいつ使用する必要がありますか?

4

2 に答える 2

13

2 つの構文はほとんどの状況で同等であり、どちらを選択するかは好みの問題です。均一な初期化に興味がある場合は、次のことをお勧めします。

A a{ A{} };

それ以外の場合は、括弧のみを使用してあいまいさを解消できます。

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

あなたの質問に示されている2つの形式が同等ではない状況が1つあることに注意してください(非常にありそうにないと言わざるを得ません)。クラス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"
}

上記の違いは、このlive exampleに示されています。

于 2013-05-31T22:49:35.793 に答える
9

ほとんどの場合、それらは同等ですが、存在する場合はコンストラクターをA a{ A() };優先し、移動/コピー コンストラクターを優先します。std::initializer_listA 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"
}
于 2013-05-31T22:50:31.720 に答える