Сообщение Re[11]: Какая версия С++ ваша основная? от 13.01.2023 14:24
Изменено 13.01.2023 14:44 rg45
Re[11]: Какая версия С++ ваша основная?
Здравствуйте, Skorodum, Вы писали:
R>>Логически фабрику можно рассматривать как некое расширение конструктора. Соответственно и стратегия обработки ошибок такая же, как в конструкторах — исключения.
S>Наверное, еще std::optional можно использовать.
Не-не-не, это по факту будет равносильно возврату к старой схеме со смарт-поинтерами. Смотрите, какие возможности предоставляет фабрика с mandatory copy/move elision:
http://coliru.stacked-crooked.com/a/4425c094d9731e2d
То есть, мы можем выбирать стратегию владения объектом за пределами фабрики — вот, что важно. Это может быть любой тип смарпоинтера, а может быть просто объект на стеке с автоматическим временем жизни. Если же изменить тип результата make_foo на std::optional<Foo>, все эти возможности тут же пропадут.
R>>Логически фабрику можно рассматривать как некое расширение конструктора. Соответственно и стратегия обработки ошибок такая же, как в конструкторах — исключения.
S>Наверное, еще std::optional можно использовать.
Не-не-не, это по факту будет равносильно возврату к старой схеме со смарт-поинтерами. Смотрите, какие возможности предоставляет фабрика с mandatory copy/move elision:
http://coliru.stacked-crooked.com/a/4425c094d9731e2d
#include <iostream>
#include <string>
#include <vector>
#include <memory>
struct Foo
{
const int id;
explicit Foo(int id) : id(id) {}
Foo() = default;
Foo(const Foo&) = delete;
Foo& operator=(const Foo&) = delete;
////////////////////////////////////////////////////////////////////////////////////////////////
Foo(Foo&&) = delete; // перемещение не обязательно запрещать явно
Foo& operator=(Foo&&) = delete; // оно автоматически запрещается, когда мы запрещаем копирование
void test() const { std::cout << "Foo: " << id << std::endl; }
};
Foo make_foo()
{
static int last_id {};
return Foo(++last_id);
}
int main()
{
auto foo = make_foo();
const auto uptr = std::unique_ptr<Foo>(new Foo(make_foo()));
const auto sptr = std::shared_ptr<Foo>(new Foo(make_foo()));
foo.test();
uptr->test();
sptr->test();
}
То есть, мы можем выбирать стратегию владения объектом за пределами фабрики — вот, что важно. Это может быть любой тип смарпоинтера, а может быть просто объект на стеке с автоматическим временем жизни. Если же изменить тип результата make_foo на std::optional<Foo>, все эти возможности тут же пропадут.
Re[11]: Какая версия С++ ваша основная?
Здравствуйте, Skorodum, Вы писали:
R>>Логически фабрику можно рассматривать как некое расширение конструктора. Соответственно и стратегия обработки ошибок такая же, как в конструкторах — исключения.
S>Наверное, еще std::optional можно использовать.
Не-не-не, это по факту будет равносильно возврату к старой схеме со смарт-поинтерами. Смотрите, какие возможности предоставляет фабрика с mandatory copy/move elision:
http://coliru.stacked-crooked.com/a/8e4325781b2be7cb
То есть, мы можем выбирать стратегию владения объектом за пределами фабрики — вот, что важно. Это может быть любой тип смарпоинтера, а может быть просто объект на стеке с автоматическим временем жизни. Если же изменить тип результата make_foo на std::optional<Foo>, все эти возможности тут же пропадут.
R>>Логически фабрику можно рассматривать как некое расширение конструктора. Соответственно и стратегия обработки ошибок такая же, как в конструкторах — исключения.
S>Наверное, еще std::optional можно использовать.
Не-не-не, это по факту будет равносильно возврату к старой схеме со смарт-поинтерами. Смотрите, какие возможности предоставляет фабрика с mandatory copy/move elision:
http://coliru.stacked-crooked.com/a/8e4325781b2be7cb
#include <iostream>
#include <string>
#include <vector>
#include <memory>
struct Foo
{
const int id;
explicit Foo(int id) : id(id) {}
Foo() = delete;
Foo(const Foo&) = delete;
Foo& operator=(const Foo&) = delete;
////////////////////////////////////////////////////////////////////////////////////////////////
Foo(Foo&&) = delete; // перемещение не обязательно запрещать явно
Foo& operator=(Foo&&) = delete; // оно автоматически запрещается, когда мы запрещаем копирование
void test() const { std::cout << "Foo: " << id << std::endl; }
};
Foo make_foo()
{
static int last_id {};
return Foo(++last_id);
}
int main()
{
auto foo = make_foo();
const auto uptr = std::unique_ptr<Foo>(new Foo(make_foo()));
const auto sptr = std::shared_ptr<Foo>(new Foo(make_foo()));
foo.test();
uptr->test();
sptr->test();
}
То есть, мы можем выбирать стратегию владения объектом за пределами фабрики — вот, что важно. Это может быть любой тип смарпоинтера, а может быть просто объект на стеке с автоматическим временем жизни. Если же изменить тип результата make_foo на std::optional<Foo>, все эти возможности тут же пропадут.