https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100612
Jonathan Wakely <redi at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Resolution|--- |INVALID Status|UNCONFIRMED |RESOLVED Severity|normal |enhancement --- Comment #6 from Jonathan Wakely <redi at gcc dot gnu.org> --- (In reply to Jonathan O'Connor from comment #5) > I was afraid you were going to say it's not a bug :-) That's why I reached > out to Nico, who was on the committee, and was one of the people who > proposed jthread. Yes, I know, I was there when we reviewed it and voted it into the standard :-) > My view, as a user, is that jthread should be a drop in replacement for > thread, with auto-joining and stop_token support. And it is. But "stop_token support" doesn't mean "can drop a stop_token at any arbitrary position in the arguments list and expect it to work". For it to work with a pointer-to-member we need to change the specification. > I've just reread the descripton of jthread's constructor here: > https://en.cppreference.com/w/cpp/thread/jthread/jthread > and it does seem to explicitly exclude the behaviour I would like. Right. > So, I have no problem with you closing this as not a bug. > Sorry for wasting your time. I guess, I'll have to write a committee > proposal. Please do. > BTW, thanks for your all your work on g++ and the stdlib++. Much appreciated. It's libstdc++ ;-) FWIW this patch makes your code work, and I think this would make a reasonable non-standard extension: diff --git a/libstdc++-v3/include/std/thread b/libstdc++-v3/include/std/thread index 886994c1320..ee4fec4a50c 100644 --- a/libstdc++-v3/include/std/thread +++ b/libstdc++-v3/include/std/thread @@ -99,6 +99,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION #ifdef __cpp_lib_jthread +#ifndef __STRICT_ANSI__ + template<typename _Callable, typename... _Args> + constexpr bool __pmf_callable_with_stop_token = false; + + template<typename _Callable, typename _Obj, typename... _Args> + constexpr bool __pmf_callable_with_stop_token<_Callable, _Obj, _Args...> + = __and_<is_member_function_pointer<remove_reference_t<_Callable>>, + is_invocable<_Callable, _Obj, stop_token, _Args...>>::value; +#endif + /// A thread that can be requested to stop and automatically joined. class jthread { @@ -211,6 +221,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION static thread _S_create(stop_source& __ssrc, _Callable&& __f, _Args&&... __args) { +#ifndef __STRICT_ANSI__ + if constexpr (__pmf_callable_with_stop_token<_Callable, _Args...>) + return _S_create2(__ssrc, std::forward<_Callable>(__f), + std::forward<_Args>(__args)...); + else +#endif if constexpr(is_invocable_v<decay_t<_Callable>, stop_token, decay_t<_Args>...>) return thread{std::forward<_Callable>(__f), __ssrc.get_token(), @@ -226,6 +242,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } } +#ifndef __STRICT_ANSI__ + template<typename _Callable, typename _Obj, typename... _Args> + static thread + _S_create2(stop_source& __ssrc, _Callable&& __f, _Obj&& __obj, + _Args&&... __args) + { + return thread{std::forward<_Callable>(__f), std::forward<_Obj>(__obj), + __ssrc.get_token(), std::forward<_Args>(__args)...}; + } +#endif + stop_source _M_stop_source; thread _M_thread; }; I think I'll make this change in my own GCC fork, but not the gcc.gnu.org version.