#include <iostream>
#include <memory>
struct A {
A() {
std::cout << "Constructor" << std::endl;
}
A(const A&) noexcept {
std::cout << "Copy constructor" << std::endl;
}
A(A&&) noexcept {
std::cout << "Move constructor" << std::endl;
}
};
struct onlyMovable {
onlyMovable() = default;
onlyMovable(onlyMovable&&) = default;
onlyMovable(const onlyMovable&) = delete; // Запрещаем копирование объекта
};
struct B {
B(A) {}
B(onlyMovable) {}
};
template <typename T, typename... Args>
std::shared_ptr<T>
factory1(Args... args)
{
return std::shared_ptr<T>(new T(std::forward<Args>(args)...));
}
template <typename T, typename... Args>
std::shared_ptr<T>
factory2(Args... args)
{
return std::shared_ptr<T>(new T(args...));
}
int main() {
std::cout << "---------------------------------" << std::endl;
std::cout << "With std::forward" << std::endl;
auto p1 = factory1<B>(A());
std::cout << "---------------------------------" << std::endl;
std::cout << "Without std::forward" << std::endl;
auto p2 = factory2<B>(A());
std::cout << "---------------------------------" << std::endl;
auto p3 = factory1<B>(onlyMovable());
//auto p4 = factory2<B>(onlyMovable()); // Ошибка компиляции, копировать этот объект нельзя
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8bWVtb3J5PgoKc3RydWN0IEEgewoJQSgpIHsKCQlzdGQ6OmNvdXQgPDwgIkNvbnN0cnVjdG9yIiA8PCBzdGQ6OmVuZGw7Cgl9CglBKGNvbnN0IEEmKSBub2V4Y2VwdCB7CgkJc3RkOjpjb3V0IDw8ICJDb3B5IGNvbnN0cnVjdG9yIiA8PCBzdGQ6OmVuZGw7Cgl9CglBKEEmJikgbm9leGNlcHQgewoJCXN0ZDo6Y291dCA8PCAiTW92ZSBjb25zdHJ1Y3RvciIgPDwgc3RkOjplbmRsOwoJfQp9OwoKc3RydWN0IG9ubHlNb3ZhYmxlIHsKCW9ubHlNb3ZhYmxlKCkgPSBkZWZhdWx0OwoJb25seU1vdmFibGUob25seU1vdmFibGUmJikgPSBkZWZhdWx0OwoJb25seU1vdmFibGUoY29uc3Qgb25seU1vdmFibGUmKSA9IGRlbGV0ZTsgLy8g0JfQsNC/0YDQtdGJ0LDQtdC8INC60L7Qv9C40YDQvtCy0LDQvdC40LUg0L7QsdGK0LXQutGC0LAKfTsKCnN0cnVjdCBCIHsKCUIoQSkge30KCUIob25seU1vdmFibGUpIHt9Cn07Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgVCwgdHlwZW5hbWUuLi4gQXJncz4Kc3RkOjpzaGFyZWRfcHRyPFQ+CmZhY3RvcnkxKEFyZ3MuLi4gYXJncykgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKewogICAgcmV0dXJuIHN0ZDo6c2hhcmVkX3B0cjxUPihuZXcgVChzdGQ6OmZvcndhcmQ8QXJncz4oYXJncykuLi4pKTsKfQoKdGVtcGxhdGUgPHR5cGVuYW1lIFQsIHR5cGVuYW1lLi4uIEFyZ3M+CnN0ZDo6c2hhcmVkX3B0cjxUPgpmYWN0b3J5MihBcmdzLi4uIGFyZ3MpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCnsKICAgIHJldHVybiBzdGQ6OnNoYXJlZF9wdHI8VD4obmV3IFQoYXJncy4uLikpOwp9CiAKaW50IG1haW4oKSB7CgkKCXN0ZDo6Y291dCA8PCAiLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIiA8PCBzdGQ6OmVuZGw7CglzdGQ6OmNvdXQgPDwgIldpdGggc3RkOjpmb3J3YXJkIiA8PCBzdGQ6OmVuZGw7CglhdXRvIHAxID0gZmFjdG9yeTE8Qj4oQSgpKTsKCXN0ZDo6Y291dCA8PCAiLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIiA8PCBzdGQ6OmVuZGw7CglzdGQ6OmNvdXQgPDwgIldpdGhvdXQgc3RkOjpmb3J3YXJkIiA8PCBzdGQ6OmVuZGw7CglhdXRvIHAyID0gZmFjdG9yeTI8Qj4oQSgpKTsKCXN0ZDo6Y291dCA8PCAiLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIiA8PCBzdGQ6OmVuZGw7CgoJCglhdXRvIHAzID0gZmFjdG9yeTE8Qj4ob25seU1vdmFibGUoKSk7IAoJLy9hdXRvIHA0ID0gZmFjdG9yeTI8Qj4ob25seU1vdmFibGUoKSk7IC8vINCe0YjQuNCx0LrQsCDQutC+0LzQv9C40LvRj9GG0LjQuCwg0LrQvtC/0LjRgNC+0LLQsNGC0Ywg0Y3RgtC+0YIg0L7QsdGK0LXQutGCINC90LXQu9GM0LfRjwp9