Синтаксис инициализации экземпляра С++

Для класса, подобного этому:

class Foo {
public:
    Foo(int);

    Foo(const Foo&);

    Foo& operator=(int);

private:
    // ...
};

Являются ли эти две строки в точности эквивалентными или есть тонкая разница между ними?

Foo f(42);

Foo f = 42;

Изменить: я смутил вопросы, сделав конструктор Foo "явным" в исходном вопросе. Я удалил это, но ценю ответы.

Я также добавил объявление конструктора копии, чтобы было ясно, что копирование не может быть тривиальной операцией.

То, что я действительно хочу знать, согласно стандарту С++, будет "Foo f = 42" напрямую вызвать конструктор Foo (int), или будет вызван конструктор копирования?

Похоже на fasih.ahmed есть ответ, который я искал (если он не ошибается).

Ответ 1

Foo f = 42;

Этот оператор создаст временный объект для значения "42".

Foo f(42);

Этот оператор будет напрямую присваивать значение, чтобы один менее функциональный вызов.

Ответ 2

class Foo {
public:
    Foo(explicit int);

    Foo& operator=(int);
};

Это недействительно. Синтаксис

class Foo {
public:
    explicit Foo(int);

    Foo& operator=(int);
};

Различие заключается в том, что конструктор преобразования не может использоваться для неявных преобразований, когда вы ставите перед ним явное:

Foo f(10); // works
Foo f = 10; // doesn't work

Вышеупомянутое не имеет ничего общего с оператором присваивания, который вы там указали. Он не используется, поскольку это инициализация (используются только конструкторы). Следующее будет использовать оператор присваивания:

Foo f;
f = 10;

И будет использовать конструктор по умолчанию Foo (тот, который не принимает никаких аргументов).


Изменить. Вопросник изменил свой вопрос на конкретные способы:

Foo f = 1; // called "copy initialization" 
Foo f(1);  // called "direct initialization"

То же самое. Ответ заключается в том, что они эквивалентны следующему:

Foo f(Foo(1));
Foo f(1);

В том случае, если конструктор преобразования, принимающий int, не объявляется с ключевым словом explicit, в противном случае первая является ошибкой компилятора (см. выше). Компилятору разрешено исключать (оптимизировать) временное переданное конструктору копирования Foo в первом случае , если все семантические ограничения все еще остаются в силе, и даже если конструктор копирования имеет побочные эффекты. Это особенно включает в себя видимый конструктор копирования.