尝试std::bind()
使用以下代码获取函数对象:
driver_manager driverManager();
std::function<void(mqtt::const_message_ptr,
mqtt::async_client*,callback*,sql::Driver*)> fn = std::bind(&driver_manager::test_callback, &driverManager, std::placeholders::_1,
std::placeholders::_2, std::placeholders::_3, std::placeholders::_4);
Run Code Online (Sandbox Code Playgroud)
结果出错:
错误:从'std::_Bind_helper<false, void (driver_manager::*)(std::shared_ptr<const mqtt::message>, mqtt::async_client*, callback*, sql::Driver*), driver_manager ( *)()、const std::_Placeholder<1>&、const std::_Placeholder<2>&、const std::_Placeholder<3>&、const std::_Placeholder<4>&>::type'非标量类型 'std::function<void(std::shared_ptr<const mqtt::message>, mqtt::async_client*, callback*, sql::Driver*)>' 请求
几个小时以来,我一直试图找出问题所在,这段代码有什么问题?
编辑
driver_manager.hpp
class driver_manager{
public:
driver_manager();
void test_callback(mqtt::const_message_ptr, mqtt::async_client*,callback*,sql::Driver*);
};
Run Code Online (Sandbox Code Playgroud)
driver_manager.cpp
driver_manager::driver_manager(){
}
void driver_manager::test_callback(mqtt::const_message_ptr msg, mqtt::async_client *client, callback *cb, sql::Driver *driver){
std::cout << "Callback triggered" << std::endl;
}
Run Code Online (Sandbox Code Playgroud) 我有这个代码构建和运行完美:
boost::function<void(string)> bar = boost::bind(&Bar::BarHandler, this, _1);
//Somewhere else in Bar.cpp
void Bar::BarHandler( std::string message ){
//Do stuff
}
Run Code Online (Sandbox Code Playgroud)
当我兴高采烈地改变boost
通过std
在上面的代码中,我开始收到此错误(我的编译器的Visual Studio 2010 SP1的):
c:\program files\microsoft visual studio 10.0\vc\include\xxpmfcaller(42): error C2664:
'void (std::string)' : cannot convert parameter 1 from 'boost::arg<I>' to 'std::string'
1> with
1> [
1> I=1
1> ]
1> No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
1> c:\program files\microsoft visual studio 10.0\vc\include\xxpmfcaller(52) : see reference to function …
Run Code Online (Sandbox Code Playgroud) 我试图在try-catch子句中包装传入的函数,以便我可以捕获它抛出的异常并在重新抛出之前进行一些清理.我编写了复制我的编译错误的示例代码.
#include <functional>
#include <iostream>
#include <queue>
#include <string.h>
#include <stdexcept>
using namespace std;
void foo(int a){
throw runtime_error("died");
}
template<class F,class ...Args>
void gen(F&& f,Args&&... args){
auto wrap = [](F f,Args... args){
try{
f(args...);
}catch(exception& e){
std::cout << "Caught exception" <<std::endl;
}
};
auto bound = std::bind(wrap, std::forward<F> (f),
std::forward<Args>(args)...);
bound();
}
int main()
{
gen(foo,5);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我似乎无法弄清楚如何将函数指针传入lambda表达式或bind调用.它似乎在调用bound()时报告错误.有人可以给出一些建议或者告诉我是否有什么我误解了吗?
我有一个派生类,从中绑定了一个我没有在此类中重写的虚函数,因此我希望调用父类中的一个。
它与 boost (1.55) 配合得很好,但如果我从 C++11 切换到 std::bind,它会拒绝使用
错误 C2100:非法间接寻址 1> 功能(1152):请参阅函数模板实例化 '_Rx std::_Pmf_wrap<_Pmf_t,_Rx,_Farg0,_V0_t,_V1_t,_V2_t,_V3_t,_V4_t,_V5_t,>::operator ()( _Wrapper &) const' 正在编译 1> with 1> [ 1> _Rx=bool, 1> _Pmf_t=bool (__thiscall Base::* )(void), 1> _Farg0=Base, 1> _V0_t=std::_Nil, 1> _V1_t=std::_Nil, 1> _V2_t=std::_Nil, 1> _V3_t=std::_Nil, 1> _V4_t=std::_Nil, 1> _V5_t=std::_Nil, 1> =std: :_Nil, 1> _Wrapper=派生 1> ]
这是最小代码
class Runnable { virtual bool Run() =0;};
class Base : public Runnable { bool Run() {/*do stuff*/ return true;}};
class Derived : public Base {};
Derived d;
std::function<bool()> …
Run Code Online (Sandbox Code Playgroud) 编辑:这个问题最初的标题是“使用std::bind
创建内联函数”,但这并不是我真正想要的:我只是想要一个简单的方法来别名函数。
我想std::chrono::high_resolution_clock::now
作为一个独立的函数公开。也就是说,我想做以下事情:
auto current_time = std::bind(std::chrono::high_resolution_clock::now);
Run Code Online (Sandbox Code Playgroud)
不幸的是,由于这是在一个头文件中,它会导致current_time
链接时的多个定义。有没有一种方法返回一个内联函数的std::bind
?
以下代码无法编译:
#include <functional>
template<class ...Args>
void invoke(Args&&... args)
{
}
template<class ...Args>
void bind_and_forward(Args&&... args)
{
auto binder = std::bind(&invoke<Args...>, std::forward<Args>(args)...);
binder();
}
int main()
{
int a = 1;
bind_and_forward(a, 2);
}
Run Code Online (Sandbox Code Playgroud)
如果我理解正确的,原因如下:std::bind
会将它的参数,当binder
的operator()
叫,它通过了所有绑定的参数作为左值 -即使是那些进入者bind
为右值.但是invoke
为原始参数进行了实例化,它无法接受binder
传递它的尝试.
这个问题有什么解决方案吗?
这是一个很长的镜头,但我想知道在javascript或node.js中是否存在C++ std :: bind这样的东西?这是我觉得需要绑定的示例:
var writeResponse = function(response, result) {
response.write(JSON.stringify(result));
response.end();
}
app.get('/sites', function(req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
dbaccess.exec(query, function(result) {
res.write(JSON.stringify(result));
res.end();
});
});
Run Code Online (Sandbox Code Playgroud)
我想传递一个带有一个参数的函数指针,而不是将回调传递给dbaccesss.exec.在C++中我会传递这个:
std::bind(writeResponse, res)
Run Code Online (Sandbox Code Playgroud)
这将导致一个函数接受一个参数(在我的情况下为'结果'),我可以传递而不是匿名回调.现在我正在为我的快递应用程序中的每个路由复制匿名函数中的所有代码.
如上所述,我想用来std::bind
创建一个函数,该函数在调用时返回一个使用带有默认参数的构造函数构建的对象,如下所示:
#include <functional>
class X
{
int x_, y_;
public:
X(int x, int y): x_(x), y_(y)
{
}
};
int main() {
auto fun = std::bind(&X::X, 1, 2);
X x = fun();
}
Run Code Online (Sandbox Code Playgroud)
相反,我收到以下编译器错误:
错误:在此上下文中,对“X”的限定引用是构造函数名称而不是类型
错误:函数式转换或类型构造需要“(”参考此行:
auto fun = std::bind(&X::X, 1, 2);
Run Code Online (Sandbox Code Playgroud) 假设我想传递一个通过std::bind
引用 funktion 创建的函数对象:
void myCallback(int i, int j)
{
std::cout << "toCall , i=" << i << " j=" << j;
}
void worker(std::function<void(int)> & callback)
{
callback(111);
}
int main(int argc, char** argv)
{
auto foo = std::bind(myCallback, std::placeholders::_1, 222);
worker(foo);
}
Run Code Online (Sandbox Code Playgroud)
这不能编译
严重性代码说明项目文件行抑制状态错误 C2664 'void worker(std::function &)': 无法将参数 1 从 'std::_Binder &,int>' 转换为 'std::function &' asn1test_1 D:.. ...\asn1test_1.....cpp 302
然而,按值传递是有效的:
void worker(std::function<void(int)> callback)
{
callback(111);
}
Run Code Online (Sandbox Code Playgroud)
当我避免使用“ auto
”并改为使用
std::function<void(int)> foo = std::bind(myCallback, std::placeholders::_1, 222);
Run Code Online (Sandbox Code Playgroud)
它既可以通过引用传递,也可以通过值传递。 …
我一直在尝试了解 std::bind 的工作原理。因此,我们要尝试不同的例子。下面是我无法理解其输出的示例程序。
版本1
class NAME
{
public:
void f()
{
std::cout<<"f"<<std::endl;
}
NAME()
{
std::cout<<"default constructor"<<std::endl;
}
NAME(const NAME&)
{
std::cout<<"copy constructor"<<std::endl;
}
};
int main()
{
std::cout << "Hello World" << std::endl;
NAME n;
std::function<void ()> callable = std::bind(&NAME::f, n);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
上述版本1的输出如下:
Hello World
default constructor
copy constructor
copy constructor
Run Code Online (Sandbox Code Playgroud)
我知道传递的参数将被复制,因此复制构造函数应该只被调用一次,但在上面的输出中复制构造函数被调用两次。为什么/怎么会发生这种情况?是否因为使用 std::bind 创建的新可调用对象将用于在 lhs 上使用 std::function 初始化另一个可调用对象?
版本2
int main()
{
std::cout << "Hello World" << std::endl;
NAME n;
std::function<void ()> callable = std::move(std::bind(&NAME::f, n));
return …
Run Code Online (Sandbox Code Playgroud) stdbind ×10
c++ ×9
c++11 ×6
auto ×2
bind ×1
boost ×1
boost-bind ×1
functor ×1
inline ×1
javascript ×1
node.js ×1
std-function ×1
visual-c++ ×1