GCC 4.7.2:带有成员函数指针的std :: thread

时间:2013-02-26 02:13:19

标签: c++ gcc c++11 std libstdc++

在编写this question的测试代码时,我发现下面的注释行无法在GCC 4.7.2上编译:

#include <thread>
#include <iostream>

struct S {
    void f() {
        std::cout << "Calling f()" << std::endl;
    }
};

int main()
{
    S s;
    // std::thread t(&S::f, s); // does not compile?
    std::thread t(&S::f, &s);
    t.join();
}

但是cppreference似乎声称“this”参数可以等效地作为对象,对象引用或指向对象的指针传递:

  

如果f是指向类T的成员函数的指针,则调用它。返回值被忽略。实际上,执行以下代码:   (t1。* f)(t2,...,tN)如果t1的类型是T,对T的引用或对从T派生的类型的引用。   ((* t1)。* f)(t2,...,tN)否则。

我实际上认为这听起来很糟糕,并且希望std::thread只允许指针或引用语义,而不是互换地接受它们,但鉴于它似乎应该是,上面是GCC / libstdc ++错误(还是我误解了cppreference)?

1 个答案:

答案 0 :(得分:4)

似乎今晚它是GCC Bug Party: - )

除了笑话,这肯定是 bug My answer to the linked question实际上包含了证明,但由于没有强调,我将在此重复。

这就是INVOKE工具的方式,std::thread的构造函数的行为(参见链接的答案)在C ++ 11标准中的定义

  

定义 INVOKE(f,t1,t2,...,tN),如下所示:

     

- (t1。* f)(t2,...,tN)当f是指向类T的成员函数的指针时,t1是一个对象   输入T或对类型为T的对象的引用或对从T派生的类型的对象的引用;

     

- ((* t1)。* f)(t2,...,tN)当f是指向类T的成员函数的指针时,t1不是   上一项中描述的类型;

     

- t1。* f当N == 1且f是指向类T的成员数据的指针时,t1是类型为T或t的对象   引用类型为T的对象或对从T派生的类型的对象的引用;

     

- (* t1)。* f当N == 1且f是指向类T的成员数据的指针时,t1不是其中一种类型   在前一项中描述;

     

- f(t1,t2,...,tN)在所有其他情况下。

粗体字的句子有效地指定了行:

  

std :: thread t(&amp; S :: f,s);

应该编译。因此,这符合错误

此外,它在GCC 4.8.0(测试版)和Clang 3.2上进行了编译。