Ответ 1
Foo f = 42;
Этот оператор создаст временный объект для значения "42".
Foo f(42);
Этот оператор будет напрямую присваивать значение, чтобы один менее функциональный вызов.
Для класса, подобного этому:
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 есть ответ, который я искал (если он не ошибается).
Foo f = 42;
Этот оператор создаст временный объект для значения "42".
Foo f(42);
Этот оператор будет напрямую присваивать значение, чтобы один менее функциональный вызов.
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 в первом случае , если все семантические ограничения все еще остаются в силе, и даже если конструктор копирования имеет побочные эффекты. Это особенно включает в себя видимый конструктор копирования.