Какая разница между делать
A a{ A() };
а также,
A a( A{} );
чтобы избежать самого неприятного разбора? Когда я должен использовать конкретный?
Какая разница между делать
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"
}
Вышеупомянутая разница показана в этом живом примере.
-fno-elide-constructors
- person Andy Prowl; 01.06.2013
-fno-elide-constructors
в настоящее время не работает на clang.
- person Mankarse; 01.06.2013
В большинстве ситуаций они эквивалентны, но 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"
}
A a;
, верно? Если я не ошибаюсь, предложенный вами синтаксис имеет смысл только тогда, когда временное значение, которое вы хотите передать конструкторуA
, имеет другой тип, чемA
, верно? т.е.A a { B() };
. - person jogojapan   schedule 04.06.2013