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.

Reply via email to