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

When writing test code for this question, I found that the line below does not compile in 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 apparently claims that the argument to "this" can be passed equivalently as an object, a reference to an object, or a pointer to an object:

If f is a pointer to a member function of class T, then it is called. The return value is ignored. The following code is effectively executed: (t1. * F) (t2, ..., tN) if the type t1 is either T, or a reference to T, or a reference to a type obtained from T. ((* t1). * F ) (t2, ..., tN) otherwise.

I really think this sounds horrible, and would prefer that std::thread can only use pointer or referential semantics instead of accepting them interchangeably, but assuming it looks like what he suggested is the above error GCC / libstdc ++ (or am I misinterpreting cppreference)?

+4
source share
1 answer

GCC Bug Party seems to be tonight :-)

Jokes aside, this is definitely a mistake . My answer to a related question does contain evidence, but since it is not underlined, I will repeat it here.

Thus, an INVOKE object, from the point of view of which the behavior of the constructor std::thread (see the related 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 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 type obtained from T;

- ((* t1). * f) (t2, ..., tN) when f is a pointer to a member function of the class T and t1 is not one of the types described in the previous paragraph;

- t1. * f, when N == 1 and f is a pointer to the data of an element of 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 type obtained from T;

- (* t1). * f, when N == 1 and f is a pointer to the data of a member of the class T and t1 is not one of the types described in the previous paragraph;

- f (t1, t2, ..., tN) in all other cases.

A bold sentence effectively indicates that the line:

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

Must compile. Therefore, this is considered a mistake .

In addition, it does string compilation on GCC 4.8.0 (beta) and Clang 3.2.

+4
source

All Articles