完美转发包装类

时间:2014-10-12 21:10:36

标签: c++ c++11 forwarding

我有一个包装类:

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

一些代理类使用T执行某些操作:

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

现在有一个创建代理的方法,我已经为l-和r-value引用重写了它:

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 个答案:

答案 0 :(得分:2)

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};
}

<强> Demo at Coliru