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.