c++ - 包装类的完美转发

标签 c++ c++11 forwarding

例如,我有一个包装器类:

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

一些代理类使用 T 做一些事情:

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

为了方便起见,现在有一个创建代理的方法,我已经为左值和右值引用编写了重载它:

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) { /* ??? */ }

那么问题来了,如何推导出左值或右值类型成员的左值或右值类型?

最佳答案

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

关于c++ - 包装类的完美转发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26330018/

相关文章:

c++ - 如何找出我的 DLL 增长如此之多的原因

c++ - 类模板的模板参数推导陷阱

iphone - Objective-C:在 iOS 中转发消息

c++ - 有人可以解释关于异常的右值引用吗?

c++ - 如何使用 rapidxml 从 xml 中读取 utf-8 字符串?

c++ - Bit hack 根据第二个值返回两个值之一

c++ - 如何在迭代时从集合中删除相邻条目

c++ - 在 C++ 自定义树的一些迭代后崩溃

c++ - 通过函数传递引用安全吗?

c++ - 为什么在没有赋值运算符的情况下调用转换构造函数?