正在为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”参数可以等效地作为对象、对象引用或对象指针传递:
If f is pointer to a member function of class T, then it is called. The return value is ignored. Effectively, the following code is executed: (t1.*f)(t2, ..., tN) if the type of t1 is either T, reference to T or reference to type derived from T. ((*t1).*f)(t2, ..., tN) otherwise.
我实际上认为这听起来很糟糕,并且更喜欢 std::thread
只允许指针或引用语义而不是互换地接受它们,但考虑到它似乎应该如此,上面是GCC/libstdc++ 错误(或者我误解了 cppreference)?
最佳答案
好像今晚是GCC Bug Party :-)
开个玩笑,这肯定是一个错误。 My answer to the linked question实际上包含证明,但由于没有强调,我将在这里重复。
这就是 INVOKE
设施的方式,std::thread
的构造函数(参见链接的答案)的行为是在 C+ 中定义的+11 标准
Define INVOKE (f, t1, t2, ..., tN) as follows:
— (t1.*f)(t2, ..., tN) when f is a pointer to a member function of a class T and t1 is an object of type T or a reference to an object of type T or a reference to an object of a type derived from T;
— ((*t1).*f)(t2, ..., tN) when f is a pointer to a member function of a class T and t1 is not one of the types described in the previous item;
— t1.*f when N == 1 and f is a pointer to member data of a class T and t1 is an object of type T or a reference to an object of type T or a reference to an object of a type derived from T;
— (*t1).*f when N == 1 and f is a pointer to member data of a class T and t1 is not one of the types described in the previous item;
— f(t1, t2, ..., tN) in all other cases.
粗体字的句子有效地指定了这一行:
std::thread t(&S::f, s);
应该编译。因此,这属于错误。
此外,它确实在 GCC 4.8.0(测试版)和 Clang 3.2 上进行了行编译。
关于c++ - GCC 4.7.2:带有指向成员函数指针的 std::thread,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15080200/