包装类的完美转发

Perfect forwarding for wrapper classes

本文关键字:转发 完美 包装类      更新时间:2023-10-16

例如,我有一个包装类:

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-值类型?

std::forward<Wrapper>(w).tw具有相同的值类别,因此您只需要返回一个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};
}

在Coliru演示