Perfect forward object
От: Videoman Россия https://hts.tv/
Дата: 02.11.22 08:39
Оценка:
Что-то сегодня плохо голова соображает. А возможен ли сабж ?
Чего хочется: маленький некопируемый неперемещаемый объект, в который передается ссылка на любой другой (возможно некопируемый и неперемещаемый) тип. При вызове метода объекта ссылка передается дальше. Что-то типа такого:
template <typename type_t>
struct object
{
    object(const type_t& type) ...
    object(const object& that) = delete;

    object& oparator(const object& that) = delete;

    const type_t& forward() const ... // as std::forward<>
};

Тут всё преобразуется к ссылке на const type, а в идеале хотелось бы std::forward<> но для класса. Возможно ли такое в принципе? Если нет, какие возможны компромиссы?
http://www.gravatar.com/avatar/60560936caa07b944d4c3cecf1c06cc5?s=80&d=identicon
Re: Perfect forward object
От: rg45 СССР  
Дата: 02.11.22 08:52
Оценка: 6 (1)
Здравствуйте, Videoman, Вы писали:

V>Что-то сегодня плохо голова соображает. А возможен ли сабж ?

V>Чего хочется: маленький некопируемый неперемещаемый объект, в который передается ссылка на любой другой (возможно некопируемый и неперемещаемый) тип. При вызове метода объекта ссылка передается дальше. Что-то типа такого:
V>
V>template <typename type_t>
V>struct object
V>{
V>    object(const type_t& type) ...
V>    object(const object& that) = delete;

V>    object& oparator(const object& that) = delete;

V>    const type_t& forward() const ... // as std::forward<>
V>};
V>

V>Тут всё преобразуется к ссылке на const type, а в идеале хотелось бы std::forward<> но для класса. Возможно ли такое в принципе? Если нет, какие возможны компромиссы?

Не уверен, что правильно понял задачу. Что-то типа такого?

template <typename T>
struct wrapper
{
  T t;

  explicit wrapper(T&& t) : t(std::forward<T>(t)) {}

  T&& forward() && { return std::forward<T>(t); }
};

template <typename T>
wrapper<T> wrap(T&& t) { return wrapper<T>(std::forward<T>(t)); }
--
Завтра сегодня будет вчера
Отредактировано 02.11.2022 10:09 rg45 . Предыдущая версия . Еще …
Отредактировано 02.11.2022 10:05 rg45 . Предыдущая версия .
Отредактировано 02.11.2022 9:40 rg45 . Предыдущая версия .
Отредактировано 02.11.2022 9:11 rg45 . Предыдущая версия .
Отредактировано 02.11.2022 8:56 rg45 . Предыдущая версия .
Отредактировано 02.11.2022 8:53 rg45 . Предыдущая версия .
Re: Perfect forward object
От: σ  
Дата: 02.11.22 09:35
Оценка: +1
V>Тут всё преобразуется к ссылке на const type, а в идеале хотелось бы std::forward<> но для класса. Возможно ли такое в принципе?

CTAD?
Re[2]: Perfect forward object
От: Videoman Россия https://hts.tv/
Дата: 02.11.22 10:20
Оценка:
Здравствуйте, rg45, Вы писали:

R>Не уверен, что правильно понял задачу. Что-то типа такого?


R>
R>template <typename T>
R>struct wrapper
R>{
R>  T t;

R>  explicit wrapper(T&& t) : t(std::forward<T>(t)) {}

R>  T&& forward() && { return std::forward<T>(t); }
R>};

R>template <typename T>
R>wrapper<T> wrap(T&& t) { return wrapper<T>(std::forward<T>(t)); }
R>


Точно, оно! Проверил вроде работает как надо, но теперь не понял как
Можно небольшую консультацию. С perfect forwarding аргументов я вроде понял, а вот тут не очень: как wrapper копирует некопируемый объект в t? Или он тип в ссылку превращает?
http://www.gravatar.com/avatar/60560936caa07b944d4c3cecf1c06cc5?s=80&d=identicon
Re[3]: Perfect forward object
От: σ  
Дата: 02.11.22 12:37
Оценка: 6 (1)
> С perfect forwarding аргументов я вроде понял, а вот тут не очень: как wrapper копирует некопируемый объект в t? Или он тип в ссылку превращает?

https://cppinsights.io/lnk?code=I2luY2x1ZGUgPHR5cGVpbmZvPgojaW5jbHVkZSA8dXRpbGl0eT4KCnRlbXBsYXRlIDx0eXBlbmFtZSBUPgpzdHJ1Y3Qgd3JhcHBlcgp7CglUIHQ7CgoJZXhwbGljaXQgd3JhcHBlcihUJiYgdCkgOiB0KHN0ZDo6Zm9yd2FyZDxUPih0KSkge30KCglUJiYgZm9yd2FyZCgpICYmIHsgcmV0dXJuIHN0ZDo6Zm9yd2FyZDxUPih0KTsgfQp9OwoKdGVtcGxhdGUgPHR5cGVuYW1lIFQ+CndyYXBwZXI8VD4gd3JhcChUJiYgdCkgeyByZXR1cm4gd3JhcHBlcjxUPihzdGQ6OmZvcndhcmQ8VD4odCkpOyB9CgpzdHJ1Y3QgdGVzdAp7Cgl0ZXN0KCkge307Cgl0ZXN0KGNvbnN0IHRlc3QmIHRoYXQpID0gZGVsZXRlOwoJdGVzdCh0ZXN0JiYgdGhhdCkgbm9leGNlcHQgPSBkZWxldGU7Cn07CgppbnQgbWFpbigpCnsKCWNvbnN0IHRlc3QgbzsKCWNvbnN0IHRlc3QmIHIgPSBvOwoKCXR5cGVpZCh3cmFwKG8pLmZvcndhcmQoKSkubmFtZSgpOwoJdHlwZWlkKHdyYXAocikuZm9yd2FyZCgpKS5uYW1lKCk7Cn0K&amp;insightsOptions=cpp17&amp;std=cpp17&amp;rev=1.0
Re[3]: Perfect forward object
От: rg45 СССР  
Дата: 02.11.22 13:21
Оценка:
Здравствуйте, Videoman, Вы писали:

R>>
R>>template <typename T>
R>>struct wrapper
R>>{
R>>  T t;

R>>  explicit wrapper(T&& t) : t(std::forward<T>(t)) {}

R>>  T&& forward() && { return std::forward<T>(t); }
R>>};

R>>template <typename T>
R>>wrapper<T> wrap(T&& t) { return wrapper<T>(std::forward<T>(t)); }
R>>


V>Точно, оно! Проверил вроде работает как надо, но теперь не понял как

V>Можно небольшую консультацию. С perfect forwarding аргументов я вроде понял, а вот тут не очень: как wrapper копирует некопируемый объект в t? Или он тип в ссылку превращает?

Здесь все зависит, от выражения, которое передается функции wrap. Для lvalue выражений тип T — это lvalue ссылка (либо константная, либо неконстантная), хоть это может быть и неочевидоно из кода. И в этом случае при использовании фунции-члена forward включается механизм reference collapsing, т.е. попросту говоря в возвращаемом результате rvalue сылка просто обрасывается и результатом выражения будет T, т.е. lvalue ссылка. В случае, если параметром функции wrap являестся rvalue выражение Т соответствует типу объекта и вот в этом случае конструктор перемещения или копирования должен быть доступен. Ну и в этом случае результатом вызова функции-члена forward будет честная rvalue ссылка.

Можно этот пример чуть переделать, если объявить член t как T&& t; В этом случае захват объекта будет выпольняться всегда по ссылке — lvalue или rvalue будет зависеть от категории выражения, переданного в функцию wrap. Такое рещение будет работать даже для кекопируемых и неперемещаемых объектов, но на программиста ложется забота об обеспечении времени жизни заврапленных временных объектов.
--
Завтра сегодня будет вчера
Re: Perfect forward object
От: Sm0ke Россия http://ksi.ru.net/
Дата: 05.11.22 15:52
Оценка:
Здравствуйте, Videoman, Вы писали:

V>Что-то сегодня плохо голова соображает. А возможен ли сабж ?

V>Чего хочется: маленький некопируемый неперемещаемый объект, в который передается ссылка на любой другой (возможно некопируемый и неперемещаемый) тип. При вызове метода объекта ссылка передается дальше. Что-то типа такого:
V>
V>template <typename type_t>
V>struct object
V>{
V>    object(const type_t& type) ...
V>    object(const object& that) = delete;

V>    object& oparator(const object& that) = delete;

V>    const type_t& forward() const ... // as std::forward<>
V>};
V>

V>Тут всё преобразуется к ссылке на const type, а в идеале хотелось бы std::forward<> но для класса. Возможно ли такое в принципе? Если нет, какие возможны компромиссы?

std::ref<> ?
Re[2]: Perfect forward object
От: Videoman Россия https://hts.tv/
Дата: 08.11.22 15:02
Оценка:
Здравствуйте, Sm0ke, Вы писали:

S>std::ref<> ?


нет!
http://www.gravatar.com/avatar/60560936caa07b944d4c3cecf1c06cc5?s=80&d=identicon
Отредактировано 08.11.2022 15:02 Videoman . Предыдущая версия .
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.