【问题标题】:std::thread constructor Is there a difference between passing a pointer and passing by ref?std::thread 构造函数传递指针和传递 ref 有区别吗?
【发布时间】:2016-03-24 13:59:43
【问题描述】:

在创建调用成员函数的线程时,传递指向当前类的指针和传递引用有区别吗?

从下面的示例中,method1 的行为是否与 method2 相同?有什么不同吗?

class MyClass
{
public:
    MyClass(){};
    ~MyClass(){};
    void memberFunction1()
    {
        //method 1
        std::thread theThread(&MyClass::memberFunction2, this, argumentToMemberFunction2)

        //method 2
        std::thread theThread(&MyClass::memberFunction2, std::ref(*this), argumentToMemberFunction2)
    }
    void memberFunction2(const double& someDouble){};
}

【问题讨论】:

  • 假设它编译,不应该有。引用是指针的语法糖。但这并不意味着它不能搞砸编译器,因为当调用(内部)以this 作为指针作为第一个对象时传递std::ref reference_wrapper 在语法上是可疑的。

标签: c++ multithreading pointers pass-by-reference member-functions


【解决方案1】:

不,没有区别,但请注意,只有在 2015 年 10 月的 WG21 会议上接受 LWG 2219 作为缺陷报告后,才能使用参考包装器。*

如果您有一个命名对象实例而不是this,使用std::ref 可能会有所帮助,因为this 很容易拼写。但请考虑以下情况,您希望在其中保持良好的 const 正确性:

A a;
std::thread(&A::foo, std::cref(a), 1, 2);

这可能比以下内容更容易阅读:

std::thread(&A::foo, &(const_cast<const A&>(a)), 1, 2);
std::thread(&A::foo, &as_const(a), 1, 2);
std::thread(&A::foo, const_cast<const A*>(&a), 1, 2);

*) 保留不同语言方言的供应商,例如带有-std 标志的 GCC 和 Clang),通常会考虑适用于所有方言的缺陷并“修复”实现。缺陷是“我们现在所说的一直都是这样”的东西。

【讨论】:

  • std::ref 示例甚至不应该编译,INVOKE 没有对 reference_wrapper 的特殊处理 - cplusplus.github.io/LWG/lwg-defects.html#2219
  • 很高兴您取消删除 :) 看起来这是最近添加到 libstdc++ - gcc.gnu.org/bugzilla/show_bug.cgi?id=59768
  • 现在确实在工作草案中,刚刚看了N4567,它的INVOKE定义包括处理reference_wrapper
  • @Praetorian:算了,它确实适用。我只是感到困惑。是的,当t1 是一个引用包装器时,LWG 问题将解释从(*t1).*f 更改为t1.get().*f,这最终使这项工作得以实现。这已被接受为缺陷报告,因此我想实施者甚至会将其修补到以前的语言方言中(例如 GCC 的 c++11c++14)。
  • @Praetorian:看来有人需要更新std::invoke 的文档。
猜你喜欢
  • 1970-01-01
  • 2023-03-31
  • 2017-06-12
  • 2014-01-29
  • 2010-10-31
  • 2022-01-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多