使用 std::bind 占位符和 boost 库的问题

Posted

技术标签:

【中文标题】使用 std::bind 占位符和 boost 库的问题【英文标题】:Issue with using std::bind placeholder along with boost library 【发布时间】:2017-11-18 01:25:12 【问题描述】:

我使用 boost 库测试框架创建了一个单元测试,但在使用 std::bind 占位符和上述库时遇到了问题。

如果我明确使用std::placeholders:: + _1,它可以正常工作:

 std::bind(&TestFixture::concatStrings, this, std::placeholders::_1, std::placeholders::_2)

但是如果我省略std::placeholders::而直接使用_1,则会导致编译错误:

Error   1   error C2664: 'std::string std::_Pmf_wrap<std::string (__thiscall TestFixture::* )(const std::string &,const std::string &),std::string,TestFixture,const std::string &,const std::string &>::operator ()(_Farg0 &,const std::string &,const std::string &) const' : cannot convert argument 2 from 'boost::arg<1>' to 'const std::string &' C:\APPS\msvs2013\VC\include\functional  1149    1   test

使用 lambda,是我能想到的最佳解决方案:

[&](const std::string& x, const std::string& y) return concatStrings(x, y); 

我只是想了解使用 std 中定义的方法是否与 boost 库冲突,例如 std::bind。提前致谢。

【问题讨论】:

【参考方案1】:

如果我明确使用 std::placeholders:: + _1,它可以正常工作:

因此,如果您正确使用它,并且如文档所述,它会起作用。

但是如果我省略 std::placeholders:: 并直接使用_1,则会导致编译错误:

如果你使用不当,它就不起作用了。

我只是想了解使用 std 中定义的方法是否与 boost 库冲突,例如 std::bind。

是的,存在命名冲突。本身并没有冲突,但不幸的是,Boost Bind 历来将它们的占位符放入全局命名空间中。

完全可以同时使用 Boost Bind ::_1、Boost Phoenix、Boost Spirit boost::spirit::qi::_1std::bind,但是是的,您可能需要限定占位符。或者,使用您自己的别名。


PS。在这种情况下,您应该可以使用std::mem_fn。如果你使用 lambdas,最好不要使用[&amp;],因为这是一个不安全的习惯。在您的情况下,您只需要捕获[this],或者如果您愿意,可以捕获[=]

【讨论】:

嗨!感谢您的回复。使用 _1 可以很好地与 boost::bind 一起使用。不过,如果我要明确使用 std::bind,我应该使用 std::placeholders::_1。感谢您指出 lambda 中的捕获,我将养成安全选择捕获的习惯。 :)

以上是关于使用 std::bind 占位符和 boost 库的问题的主要内容,如果未能解决你的问题,请参考以下文章

将 std::bind 应用于带有参数 <boost::asio::ip::tcp::socket> 的函数时出错?

如何使用左侧的占位符和右侧的编辑文本创建 UITextField?

Swift iOS 8+ UISearchBar图标,占位符和文本居中

如何在构建时使用占位符和导航组件创建 Deeplink

占位符和参数的区别

使用占位符和错误验证为 CreateView 和 UpdateView 制作自定义模板