Что-то сегодня плохо голова соображает. А возможен ли сабж ?
Чего хочется: маленький некопируемый неперемещаемый объект, в который передается ссылка на любой другой (возможно некопируемый и неперемещаемый) тип. При вызове метода объекта ссылка передается дальше. Что-то типа такого:
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<> но для класса. Возможно ли такое в принципе? Если нет, какие возможны компромиссы?
Здравствуйте, 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)); }
Здравствуйте, 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? Или он тип в ссылку превращает?
Здравствуйте, 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. Такое рещение будет работать даже для кекопируемых и неперемещаемых объектов, но на программиста ложется забота об обеспечении времени жизни заврапленных временных объектов.
Здравствуйте, 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<> ?