在编写测试代码时这个问题 https://stackoverflow.com/questions/15080015/stdthread-with-pointer-to-data-member我发现下面的注释行无法在 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)?
看来今晚是GCC 错误派对 https://stackoverflow.com/questions/15079947/obviously-ambiguous-call-does-not-cause-a-compilation-error-on-gcc#comment21209484_15079947 :-)
抛开笑话不谈,这肯定是一个bug. 我对链接问题的回答 https://stackoverflow.com/questions/15080015/stdthread-with-pointer-to-data-member/15080378#15080378其实已经有证明了,但由于没有强调,所以这里再重复一下。
这就是如何INVOKE
设施,就其行为而言std::thread
的构造函数(请参阅链接的答案)在 C++11 标准中定义
Define 调用 (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 或 a 的对象时
对类型 T 的对象的引用或对从 T 派生的类型的对象的引用;
— (*t1).*f 当 N == 1 并且 f 是指向类 T 的成员数据的指针并且 t1 不是其中一种类型时
前一项中描述;
— 在所有其他情况下为 f(t1, t2, ..., tN)。
粗体字的句子有效地指定了该行:
std::thread t(&S::f, s);
应该编译。因此,这符合bug.
此外,它可以在 GCC 4.8.0(测试版)和 Clang 3.2 上进行行编译。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)