[英]std::bind fails to compile with std::atomic_bool& on MSVC
I'm using VC++ to compile my program (using Visual Studio 2015, update 3) and some snippet fails to compile. 我正在使用VC ++编译我的程序(使用Visual Studio 2015更新3),并且某些代码段无法编译。
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. bind
总是尝试存储参数的值 ,而不是引用。 atomic
types cannot be copied. atomic
类型无法复制。 So when bind
tries to copy them, it will fail. 因此,当bind
尝试复制它们时,它将失败。
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. 这是reference_wrapper
存在的原因之一:允许在期望值的地方使用对对象的引用。 Indeed, std::ref
was invented primarily to deal with bind
. 确实, std::ref
发明主要是为了处理bind
。
See, bind
could have stored references to parameters. 看, bind
可能已经存储了对参数的引用。 However, storing references can be very dangerous, especially references to stack variables which may stop existing sometime before the bind
functor gets called. 但是,存储引用可能非常危险,尤其是对堆栈变量的引用,这些引用可能在调用bind
函子之前的某个时间停止存在。 So bind
forces you to be explicit about when you store references; 因此, bind
强制您明确存储引用的时间; it makes you use ref
. 它使您使用ref
。
std::atomic
types are not CopyConstructible. std::atomic
类型不是CopyConstructible。 Your (erroring) invocations to std::bind()
would create copies. 您(错误)对std::bind()
)的调用将创建副本。
Additionally, you appear to misunderstand how references work - auto& ref = b
does of course create a reference to b
; 另外,您似乎误解了引用的工作方式auto& ref = b
当然会创建对b
的引用; but ref
is still an lvalue in its own right and as such, passing it to std::bind()
does not suddenly change the behaviour. 但是ref
本身仍然是左值,因此将ref
传递给std::bind()
不会突然改变其行为。
Finally, considering you're using atomics, which is C++11, this means you also have access to lambdas which would allow you to express your code without having to resort to std::ref
: 最后,考虑到您使用的是A ++(C ++ 11)原子,这意味着您还可以访问lambda,这将使您无需借助std::ref
即可表达代码:
std::function<void()> delegate = [&b] { b = true; };
Beware however! 但是要当心! In either case, whether you use std::bind
+ std::ref
or my lambda example above, you must ensure that b
remains valid until you are done with delegate
- taking a reference does not extend the original object's lifetime. 无论哪种情况,无论您使用的是std::bind
+ std::ref
还是上面的lambda示例,您都必须确保b
保持有效,直到您完成delegate
为止-引用不会延长原始对象的寿命。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.