0

I know if I want to apply call by reference via std::thread, I should wrap passing argument with std::ref as std::reference_wrapper to be copy-able. I met a compile failure when I try to directly pass a named int variable with function accepting int&. This is nice and gives a hint I should wrap it with std::ref.

auto f = [](int&) {};
int obj;
std::thread t(f, obj);            // compile failure                               
std::thread t2(f, std::ref(obj)); // ok

Error message on Visual Studio 2015: pastebin

But in the case with user-defined object, it looks like no such compile error to give the hint. Of course the call by reference does not work, the passed value is not affected after thread completed.

struct MyObject { int i; MyObject(): i(0){} };

auto f = [](MyObject& obj) { obj.i = 100 };
MyObject obj;
std::thread t(f, obj); // compile fine
// obj.i is still 0

Why does compiler allow to compile if type is not built-in type for this wrong usage?

Updated:

I am using MS Visual Studio 2015. This issue does not happen on gcc.

Thanks to chris and T.C. After disabled the visaul studio language extension, both user-defined object and built-in types are not allowed to compile.

It looks like caused by a MS extension.

Community
  • 1
  • 1
Chen OT
  • 3,486
  • 2
  • 24
  • 46
  • 1
    [Doesn't work with Clang](http://coliru.stacked-crooked.com/a/9e99d8323e4497fc). Try it with language extensions disabled on VS and see if that makes a difference. – chris Nov 25 '15 at 03:03
  • 1
    Typical behavior with the MSVC extension allowing a non-const lvalue reference to bind to an rvalue (though apparently only for non-built-in types). – T.C. Nov 25 '15 at 03:04
  • Yeah, I try it on Wandbox with gcc, User-defined object also caused compile error. I am going to try to disable VS extension. – Chen OT Nov 25 '15 at 03:04
  • @chris After disabled Visual Studio, the user-defined object case is also compile error. Thanks. I have not thought it is a VS specific thing. – Chen OT Nov 25 '15 at 03:08
  • You shouldn't have to disable extensions (sometimes that's not an option because things like `Windows.h` fail to compile without them); setting the warning level to `/W4` should cause warnings about binding an rvalue to a non-const lvalue reference. – Praetorian Nov 25 '15 at 05:26
  • Yes. I am just working on a compile error issue because one of my library includes to use win32 API. It looks not so easy to ensure not touch that... – Chen OT Nov 25 '15 at 05:38
  • Possible duplicate of [Why does passing object reference arguments to thread function fails to compile?](http://stackoverflow.com/questions/8299545/why-does-passing-object-reference-arguments-to-thread-function-fails-to-compile) – Jonathan H Nov 25 '15 at 12:08
  • @Sh3ljohn it's cool that question's situation is opposed to mine. He is fine in int& but failed in non-builtin type. – Chen OT Nov 25 '15 at 12:13
  • @ChenOT Although wondering about why MSVC causes this behaviour with language extension is fair enough, passing by reference to a thread function should always involve reference wrappers (eg `std::ref` or `std::cref`). With wrappers, both of your examples should compile fine. So I think this question is not really a programming one, and therefore doesn't really belong on SO. It should simply be a bug report to MSVC, don't you think? – Jonathan H Nov 25 '15 at 12:22

0 Answers0