GCC 4.7.2: std::thread with pointer to member function

和自甴很熟 提交于 2020-01-03 18:32:14

问题


In writing test code for this question I found that the commented line below does not compile on 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();
}

But cppreference seems to claim that the "this" argument can be passed equivalently as an object, reference to object, or pointer to object:

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.

I actually think this sounds terrible, and would prefer std::thread only allow either pointer or reference semantics instead of accepting them interchangeably, but given that it seems like it's supposed to, is the above a GCC/libstdc++ bug (or am I misinterpreting cppreference)?


回答1:


Seems like tonight it's GCC Bug Party :-)

Jokes aside, this is most certainly a bug. My answer to the linked question actually contains the proof, but since it is not emphasized, I will repeat it here.

This is how the INVOKE facility, in terms of which the behavior of std::thread's constructor (see the linked answer) is defined in the C++11 Standard

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.

The sentence in bold font effectively specifies that the line:

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

Should compile. Therefore, this qualifies as a bug.

Besides, that does line compile on GCC 4.8.0 (beta) and Clang 3.2.



来源:https://stackoverflow.com/questions/15080200/gcc-4-7-2-stdthread-with-pointer-to-member-function

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!