我不喜欢在我的代码中散布着魔术盒......这两个类究竟是如何工作的,基本上允许任何函数映射到一个函数对象,即使函数<>有一个完全不同的参数设置为一个im传递给 boost::bind
它甚至适用于不同的调用约定(即成员方法__thiscall在VC下,但"普通"函数通常__cdecl或者__stdcall需要与C兼容的那些).
以下代码导致cl.exe崩溃(MS VS2005).
我试图使用boost bind来创建一个调用myclass方法的函数:
#include "stdafx.h"
#include <boost/function.hpp>
#include <boost/bind.hpp>
#include <functional>
class myclass {
public:
void fun1() { printf("fun1()\n"); }
void fun2(int i) { printf("fun2(%d)\n", i); }
void testit() {
boost::function<void ()> f1( boost::bind( &myclass::fun1, this ) );
boost::function<void (int)> f2( boost::bind( &myclass::fun2, this ) ); //fails
f1();
f2(111);
}
};
int main(int argc, char* argv[]) {
myclass mc;
mc.testit();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我究竟做错了什么?
使用boost-bind,生成的boost函数可能会收到比绑定对象所期望的更多的参数.概念:
int func() { return 42; }
boost::function<int (int,int,int)> boundFunc = boost::bind(&func);
int answer = boundFunc(1,2,3);
Run Code Online (Sandbox Code Playgroud)
在这种情况下,func()即使其签名表明它不带参数,也会在堆栈上接收1,2和3.
这不同于更典型的使用boost::bind用于局部应用,其中的值是固定的,产生了一定的对象boost::function即需要更少的参数,但是提供正确的参数数调用绑定对象时.
以下代码适用于MSVC++ 2010 SP1.这是一种简化形式的帖子; 原始代码也适用于Linux上的g ++ 4.4.
以下是根据C++标准明确定义的吗?
#include <iostream>
#include <boost/bind.hpp>
#include <boost/function.hpp>
using namespace std;
void func1(int x) { std::cout << "func1(" << x << ")\n"; } // end func1()
void func0() { std::cout << "func0()\n"; } // end func0()
int main(int argc,char* argv[])
{
typedef boost::function<void …Run Code Online (Sandbox Code Playgroud) 我有一个函数,我想将一个可选的boost :: function参数作为报告错误条件的回调.是否有一些特殊值我可以使用默认值使其可选?
例如,使用常规函数指针,我可以这样做:
void my_func(int a, int b, t_func_ptr err_callback=NULL) {
if (error && (err_callback != NULL))
err_callback();
}
Run Code Online (Sandbox Code Playgroud)
我可以用boost :: function替换函数指针做类似的事吗?
我有一些非常基本的测试代码.我有一个类,只记录它上面的所有操作.我将它绑定到这样的boost::function对象:
void Function(const Foo&)
{
printf("Function invoked\n");
}
// ...
boost::function<void(void)> func;
{
Foo f;
printf("\nConstructing function\n");
func = boost::bind(&Function, f);
printf("Construction complete\n\n");
}
Run Code Online (Sandbox Code Playgroud)
我希望函数对象包含一个副本f.因此,必须至少创建一个副本.但是,我发现我得到了13个临时工.输出是:
Constructing function
Foo::Foo(const Foo&)
Foo::Foo(const Foo&)
Foo::Foo(const Foo&)
Foo::Foo(const Foo&)
Foo::~Foo
Foo::Foo(const Foo&)
Foo::~Foo
Foo::~Foo
Foo::Foo(const Foo&)
Foo::Foo(const Foo&)
Foo::Foo(const Foo&)
Foo::Foo(const Foo&)
Foo::Foo(const Foo&)
Foo::Foo(const Foo&)
Foo::Foo(const Foo&)
Foo::~Foo
Foo::~Foo
Foo::~Foo
Foo::~Foo
Foo::~Foo
Foo::Foo(const Foo&)
Foo::~Foo
Foo::Foo(const Foo&)
Foo::~Foo
Foo::~Foo
Foo::~Foo
Foo::~Foo
Construction complete
Run Code Online (Sandbox Code Playgroud)
我不能使用ref或cref …
在某些情况下std::function可以取代继承.以下两个代码片段非常相似(调用函数时的成本大致相同,签名中的用法几乎相同,在大多数情况下,std :: function也不需要我们制作额外的副本A):
struct Function
{
virtual int operator()( int ) const =0;
};
struct A
: public Function
{
int operator()( int x ) const override { return x; }
};
Run Code Online (Sandbox Code Playgroud)
使用std::function,我们可以重写为
using Function = std::function<int (int)>;
struct A
{
int operator()( int x ) const { return x; }
};
Run Code Online (Sandbox Code Playgroud)
为了更清楚,两个片段是如何相关的:它们都可以通过以下方式使用:
int anotherFunction( Function const& f, int x ) { return f( x ) + f( x ); }
int main( int …Run Code Online (Sandbox Code Playgroud) 图书馆代码:
class Resource
{
public:
typedef void (*func_sig)(int, char, double, void*);
//Registration
registerCallback(void* app_obj, func_sig func)
{
_app_obj = app_obj;
_func = func;
}
//Calling when the time comes
void call_app_code()
{
_func(231,'a',432.4234,app_obj);
}
//Other useful methods
private:
void* app_obj;
func_sig _func;
//Other members
};
Run Code Online (Sandbox Code Playgroud)
申请代码:
class App
{
public:
void callme(int, char, double);
//other functions, members;
};
void callHelper(int i, char c, double d, void* app_obj)
{
static_cast<App*>(app_obj)->callme(i,c,d);
}
int main()
{
App a;
Resource r;
r.registercallback(&a, callHelper);
//Do …Run Code Online (Sandbox Code Playgroud) 我写了一些代码并且害怕它不起作用 - 所以我写了一个原型:
#include <boost/function.hpp>
#include <boost/bind.hpp>
#include <iostream>
class base {
private:
boost::function<void (int)> action;
protected:
virtual void onDataBaseReady(int i) { std::cout << i << std::endl; }
public:
void call() {
action(10);
}
base() {
action = boost::bind(&base::onDataBaseReady, this, _1);
}
};
class child : public base {
protected:
virtual void onDataBaseReady(int i) { std::cout << i+10 << std::endl; }
};
int main()
{
static child c;
c.call();
std::cin.get();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
编译和工作.(输出20).但为什么?我也在VS2010下进行了测试,并想知道它是否适用于跨平台(比如在GCC下编译)?
主要是action = boost::bind(&base::onDataBaseReady, …
有些C++对象没有复制构造函数,但有移动构造函数.例如,boost :: promise.如何使用移动构造函数绑定这些对象?
#include <boost/thread.hpp>
void fullfil_1(boost::promise<int>& prom, int x)
{
prom.set_value(x);
}
boost::function<void()> get_functor()
{
// boost::promise is not copyable, but movable
boost::promise<int> pi;
// compilation error
boost::function<void()> f_set_one = boost::bind(&fullfil_1, pi, 1);
// compilation error as well
boost::function<void()> f_set_one = boost::bind(&fullfil_1, std::move(pi), 1);
// PS. I know, it is possible to bind a pointer to the object instead of
// the object itself. But it is weird solution, in this case I will have
// to take cake …Run Code Online (Sandbox Code Playgroud) 我正在尝试编写一个函数,它将一个仿函数作为参数,调用仿函数,然后返回包含在一个函数中的返回值boost::shared_ptr.
以下拒绝编译,我完全没有想法.我得到"std :: vector <std :: string>不提供调用操作符"(粗略地).我在Mac OS X上使用Clang 3.1.
template< typename T >
boost::shared_ptr< T > ReturnValueAsShared(
boost::function< T() > func )
{
return boost::make_shared< T >( func() );
}
Run Code Online (Sandbox Code Playgroud)
这是我尝试使用它的上下文:
make_shared< packaged_task< boost::shared_ptr< std::vector< std::string > > > >(
bind( ReturnValueAsShared< std::vector< std::string > >,
bind( [a function that returns a std::vector< std::string >] ) ) );
Run Code Online (Sandbox Code Playgroud)
编辑:这是一个完整的独立测试用例.这段代码无法使用相同的错误进行编译,对于我的生活,我看不出有什么问题:
#include <boost/make_shared.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/function.hpp>
#include <boost/bind.hpp>
#include <string>
#include <vector>
std::vector< std::string > foo( std::string a …Run Code Online (Sandbox Code Playgroud) boost-function ×10
c++ ×9
boost ×6
boost-bind ×6
c++11 ×2
arguments ×1
boost-thread ×1
default ×1
function ×1
std-function ×1
templates ×1