在编写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)?
答案 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上进行了编译。