I'm using VC++ to compile my program (using Visual Studio 2015, update 3) and some snippet fails to compile.
basically, I want to bind a function which gets a reference to atomic boolean with atomic boolean. self containing code:
void stub(std::atomic_bool& b) {
b = true;
}
int main() {
std::atomic_bool b(false);
std::function<void()> delegate = std::bind(stub, b); //fails to compile
auto& ref = b;
std::function<void()> delegate0 = std::bind(stub, ref); //fails to compile
std::function<void()> delegate1 = std::bind(stub, std::ref(b)); //compiled
/*...*/
}
the compiler stack trace:
1>c:\program files (x86)\microsoft visual studio 14.0\vc\include\xutility(357): error C2665: 'std::tuple<std::atomic<bool>>::tuple': none of the 2 overloads could convert all the argument types
1> c:\program files (x86)\microsoft visual studio 14.0\vc\include\tuple(608): note: could be 'std::tuple<std::atomic<bool>>::tuple(std::tuple<std::atomic<bool>> &&)'
1> c:\program files (x86)\microsoft visual studio 14.0\vc\include\tuple(607): note: or 'std::tuple<std::atomic<bool>>::tuple(const std::tuple<std::atomic<bool>> &)'
1> c:\program files (x86)\microsoft visual studio 14.0\vc\include\xutility(357): note: while trying to match the argument list '(std::atomic<bool>)'
1> c:\program files (x86)\microsoft visual studio 14.0\vc\include\functional(866): note: see reference to function template instantiation 'std::_Compressed_pair<void (__cdecl *)(std::atomic_bool &),std::tuple<std::atomic<bool>>,false>::_Compressed_pair<void(__cdecl &)(std::atomic_bool &),_Cv_TiD&>(std::_One_then_variadic_args_t,_Other1,_Cv_TiD &)' being compiled
1> with
1> [
1> _Cv_TiD=std::atomic<bool>,
1> _Other1=void (__cdecl &)(std::atomic_bool &)
1> ]
1> c:\program files (x86)\microsoft visual studio 14.0\vc\include\functional(864): note: see reference to function template instantiation 'std::_Compressed_pair<void (__cdecl *)(std::atomic_bool &),std::tuple<std::atomic<bool>>,false>::_Compressed_pair<void(__cdecl &)(std::atomic_bool &),_Cv_TiD&>(std::_One_then_variadic_args_t,_Other1,_Cv_TiD &)' being compiled
1> with
1> [
1> _Cv_TiD=std::atomic<bool>,
1> _Other1=void (__cdecl &)(std::atomic_bool &)
1> ]
1> c:\program files (x86)\microsoft visual studio 14.0\vc\include\functional(863): note: while compiling class template member function 'std::_Binder<std::_Unforced,void (__cdecl &)(std::atomic_bool &),std::atomic_bool &>::_Binder(_Fx,std::atomic_bool &)'
1> with
1> [
1> _Fx=void (__cdecl &)(std::atomic_bool &)
1> ]
1> c:\program files (x86)\microsoft visual studio 14.0\vc\include\functional(890): note: see reference to function template instantiation 'std::_Binder<std::_Unforced,void (__cdecl &)(std::atomic_bool &),std::atomic_bool &>::_Binder(_Fx,std::atomic_bool &)' being compiled
1> with
1> [
1> _Fx=void (__cdecl &)(std::atomic_bool &)
1> ]
1> c:\visual studio 2015\projects\quantum\quantum\main.cpp(658): note: see reference to class template instantiation 'std::_Binder<std::_Unforced,void (__cdecl &)(std::atomic_bool &),std::atomic_bool &>' being compiled
Is there something I miss or it's the compiler fault?
bind
always tries to store values of the parameters, never references.atomic
types cannot be copied. So whenbind
tries to copy them, it will fail.This is one of the reasons
reference_wrapper
exists: to allow a reference to an object to be used in a place where a value is expected. Indeed,std::ref
was invented primarily to deal withbind
.See,
bind
could have stored references to parameters. However, storing references can be very dangerous, especially references to stack variables which may stop existing sometime before thebind
functor gets called. Sobind
forces you to be explicit about when you store references; it makes you useref
.