c++ - GCC 4.7.2:带有指向成员函数指针的 std::thread

标签 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”参数可以等效地作为对象、对象引用或对象指针传递:

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/

相关文章:

c++ - 如何选择编译应用程序的 Visual C++ 库版本?

c++ - std::string 中的段错误

c++ - RegSetValueEx 将不正确的数据输入注册表

c++ - 使用 Eclipse 在 Windows 中为 Linux 编译 C++ 程序?

iphone - 如何在 iPhone 上使用 GNU C 编译器/gcc 和移动终端编译简单的 C 文件?

c++ - 我如何告诉 clang-format 缩进可见性修饰符?

c++ - 尽管使用指令,gcc 11.3.0 仍找不到运算符

c++ - 如何仅在本地 header 上运行预处理器?

c++ - 没有模板左值不匹配(&&),但有模板匹配(T &&)?

c++ - 如何迭代boost graph以获取顶点的传入和传出边缘?