std::thread构造函数:传递指针和传递引用有什么区别吗?

9

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

从下面的示例中,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){};
}

2
假设它编译通过,就不应该有问题。引用是指针的语法糖。但这并不意味着它不能搞乱编译器,因为在使用std::ref reference_wrapper作为第一个对象(内部)指针调用时,将其作为引用传递在语法上是可疑的。 - ShadowRanger
1个回答

4

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

在您拥有命名对象实例而不是this的情况下,使用std :: ref可能会有所帮助,因为this很容易拼写错误。但请考虑以下情况,您希望保持良好的const-correct:

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

*) 保留不同语言方言的供应商(例如GCC和Clang使用-std标志),通常会认为缺陷适用于所有方言,并“修复”实现。 缺陷是指“一直以来都应该是我们现在所说的方式”的事情。


std::ref 的例子甚至不应该编译,INVOKEreference_wrapper 没有特殊处理 - https://cplusplus.github.io/LWG/lwg-defects.html#2219 - Praetorian
很高兴你已经恢复了 :) 看起来这是最近添加到libstdc++中的- https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59768 - Praetorian
它确实在工作草案中,刚刚查看了N4567,其中INVOKE的定义包括处理reference_wrapper - Praetorian
@Praetorian:算了,它确实适用。我只是有点困惑。是的,LWG问题将解释从(*t1).*f更改为t1.get().*f,当t1是引用包装器时,这最终使其工作。这已被接受为缺陷报告,因此我认为实现者甚至会将其修补到以前的语言方言中(例如GCC的c++11c++14)。 - Kerrek SB
@Praetorian:看起来有人需要更新std::invoke的文档。 - Kerrek SB
也许TC或Cubbi会看到这个答案并且完成它 :) “可能的实现”还需要添加一些解包代码。 - Praetorian

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接