[cfe-dev] thread(F&&) fails when F is not MoveAssignable

Gordon Henriksen gordonhenriksen at me.com
Sun Dec 16 14:22:36 PST 2012


[Sorry for the cross-post, but cfe-users doesn't seem to be active yet.]

The snippet at the end of this message fails to compile with clang-libc++.

Is LaunchByMove() invalid C++11, or is this a libc++ bug?

I have a body of code written using the failing LaunchByMove pattern. I guess
I'll have to work around the issue, perhaps with the LaunchByCopy pattern.
Enforcing that style may prove error-prone, though.

The relevant section in N3242 is this:

  30.3.1.2  thread constructors
  …

  template <class F, class ...Args> explicit thread(F&& f, Args&&... args);

  Given a function as follows:

    template <class T> typename decay<T>::type decay_copy(T&& v)
      { return std::forward<T>(v); }

  Requires: F and each Ti in Args shall satisfy the MoveConstructible
  requirements. INVOKE(decay_copy(std::forward<F>(f)),
  decay_copy(std::forward<Args>(args))...) (20.8.2) shall be a valid
  expression.

There doesn't appear to be any Swappable or MoveAssignable requirement for
template argument F, at least in the draft.

— Gordon


cat <<'EOT' >test.cpp
#include <thread>
class CopyableNotAssignable {
  int &n_;
public:
  CopyableNotAssignable(int &n) : n_(n) { }
};
void LaunchByMove() {
  int n;
  std::thread(CopyableNotAssignable(n)).join(); // expect-error
}
void LaunchByCopy() {
  int n;
  CopyableNotAssignable cna(n);
  std::thread(cna).join(); // successful
}
EOT
xcrun clang -std=c++0x -stdlib=libc++ -c test.cpp


Output:
In file included from test.cpp:1:
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/thread:330:5: error: 
    attempt to use a deleted function
  __invoke(_VSTD::move(_VSTD::get<0>(__t)), ...
  ^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/thread:340:5: note: 
    in instantiation of function template specialization
    'std::__1::__threaad_execute<CopyableNotAssignable, , >' requested here
  __threaad_execute(*__p, _Index());
  ^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/thread:352:41: note: 
    in instantiation of function template specialization
    'std::__1::__thread_proxy<std::__1::tuple<CopyableNotAssignable> >'
    requested here
  int __ec = pthread_create(&__t_, 0, &__thread_proxy<_Gp>, __p.get());
                                      ^
test.cpp:9:3: note: in instantiation of function template specialization
    'std::__1::thread::thread<CopyableNotAssignable, , void>' requested here
std::thread(CopyableNotAssignable(n)).join();
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/type_traits:825:5: note: 
    function has been explicitly marked deleted here
  ~__nat() = delete;
  ^
1 error generated.





More information about the cfe-dev mailing list