Идеальная пересылка для классов-обёрток

У меня есть, например, класс оболочки:

template <typename T>
struct Wrapper {
T t;
};

И некоторый прокси-класс, который принимает что-то с T:

template <typename T>
struct Proxy {
T t;
void operator()() const {/* .... */}
}

Теперь для удобства есть метод, который создает прокси, и я написал перегруженный для справки по l- и r-значению:

template <typename T>
Proxy<const T &> createProxy(const Wrapper<T> &w) {return {w.t};}

template <typename T>
Proxy<T> createProxy(Wrapper<T> &&w) {return {std::move(w.t)};}

Это, конечно, просто урезанный код, который я хотел использовать, но чтобы сделать все более читабельным, я хочу использовать некоторую совершенную магию пересылки, которая приводит к уменьшению кода, делая все немного более читабельным:

template <typename Wrapper>
Proxy</* ??? */> createProxy(Wrapper &&w) { /* ??? */ }

Итак, вопрос в том, как я могу вычесть тип значения l или r члена типа значения l или r?

1

Решение

std::forward<Wrapper>(w).t имеет ту же категорию значений, что и wтак что все, что вам нужно сделать, это вернуть Proxy с && раздели от decltype((std::forward<Wrapper>(w).t)):

template <typename T>
struct remove_rvalue_reference {
using type = T;
};

template <typename T>
struct remove_rvalue_reference<T&&> {
using type = T;
};

template <typename T>
using remove_rvalue_reference_t = typename remove_rvalue_reference<T>::type;

template <typename Wrapper>
auto createProxy(Wrapper&& w) ->
Proxy<remove_rvalue_reference_t<decltype((std::forward<Wrapper>(w).t))>> {
return {std::forward<Wrapper>(w).t};
}

Демо в Колиру

2

Другие решения


По вопросам рекламы [email protected]