微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

`std::thread` 对象的构造函数中的 `decay_copy` 有什么作用?

如何解决`std::thread` 对象的构造函数中的 `decay_copy` 有什么作用?

我试图理解 std::thread 的构造函数,但无法理解如何表示/处理参数类型。从 cppreference 来看,一个简化的构造函数可以勾画如下:

class thread {
   public:
    template <class Function,class Arg>
    thread(Function&& f,Arg&& arg) {
        // something happening
        std::invoke(decay_copy(std::forward<Function>(f)),decay_copy(std::forward<Arg>(arg)));
        // something else happening
    }
};

cppreference 将 decay_copy 定义为:

template <class T>
std::decay_t<T> decay_copy(T&& v) { return std::forward<T>(v); }

我用以下示例进行了一些实验:

struct X{};
int main() {
    X x1{};
    X& x2 = x1;
    auto f = []() { return; };
    thread t1{f,x1}; // arg should be of type X& after the inner std::forward<Arg>(arg);
    thread t2{f,x2}; // arg should be of type X& after the inner std::forward<Arg>(arg);
    thread t3{f,X{}}; // arg should be of type X&& after the inner std::forward<Arg>(arg);
}

根据我的分析,x1x2 都是内部 std::forward 之后的左值引用类型,而X{} 是右值引用类型。我相信我们需要以某种方式将 x1x2 分开以按值或按引用传递它。分析将我引向三个问题:

  • 以上分析是否正确?
  • decay_copy 如何正确解开类型?
  • 开始一段时间后,我想知道:哦,打扰了,为什么会如此牵扯?可以更容易吗?答案当然是否定的,但我对整个操作仍然缺乏直觉。

感谢您的任何提示、建议或解释!

解决方法

标准线程复制(或移动)到参数类型的衰减版本中。衰减后的版本既不是引用也不是 const 也不是 volatile 也不是数组(数组和函数变成了指针)。

如果您需要左值引用参数,请使用引用包装器。否则线程构造函数中被调用的函数将获得一个右值;衰减复制仅确定您在线程函数中传递的右值是如何从 std 线程参数构造的。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。