我必须将函数传递给指针.为此我正在使用boost :: function.对于不同的签名,捕获指针的函数被重载.例如:
void Foo(boost::function<int ()>) { ... }
void Foo(boost::function<float ()>) { ... }
void Foo(boost::function<double ()>) { ... }
Run Code Online (Sandbox Code Playgroud)
现在我想在那里传递一些类方法指针:
class test
{
public:
float toCall() { };
};
class Wrapper
{
Wrapper() {
test obj;
Foo(boost::bind(&test::toCall, this));
}
};
error: no matching function for call to ‘Foo(boost::_bi::bind_t<float, boost::_mfi::mf0<float, test>, boost::_bi::list1<boost::_bi::value<Wrapper*> > >)’
note: candidates are: Foo(boost::function<float()>&)
Run Code Online (Sandbox Code Playgroud) 假设我有方法:
void foo(const std::string& s);
Run Code Online (Sandbox Code Playgroud)
我可以创建boost :: function:
boost::function<void(const std::string&)> f = boost::bind(foo, temp);
Run Code Online (Sandbox Code Playgroud)
其中temp是char*,在f被调用之前被删除.
我正在编写一个类,其中一个函数的实现取决于用户.目前我将它作为虚函数,用户需要覆盖我的类来提供它的实现.我正在考虑使它成为一个仿函数(boost :: function)/ function_pointer,以便用户可以注册它.应用程序对性能至关重要,速度比看起来不错的类更重要.改为仿函数会带来一些性能上的好处吗?
在大多数情况下,它将是一个自由函数,因此函数指针应该没问题.但我想有些情况可能需要状态,因此它需要成为一个仿函数.
允许注册一个function_ptr或一个仿函数并根据某些bool调用合适的一个,我是否会获得任何性能优势?类似的东西.
class Myclass
{
public:
registerFuncPtr(FuncPtrSignature);
registerFunctor(boost::function func);
private:
someMethod(someArgs)
{
...
if(_isFuncPtr)
_func_ptr(args);
else
_functor(args);
...
}
bool _isFuncPtr;
FuncptrSignature _func_ptr;
boost::function _functor;
}
Run Code Online (Sandbox Code Playgroud)
更新:
我正在编写一个共享库,客户端将动态链接它.没有C++ 0x.:(
我想使用 aboost::function并将其传递给一个函数作为回调函数。我似乎在为它分配成员函数时遇到了一些麻烦。
我想传递给它的函数是一个静态函数(因为它是在另一个线程上调用的)。
boost::function<std::string (ResolverReply& reply)> call_back = std::bind1st(std::mem_fun(&ResolverCommunicator::reply_call_back), *this);
Run Code Online (Sandbox Code Playgroud)
这是在ResolverCommunicator课堂上,但我的编译器抱怨:
_Right: reference to reference is illegal
c:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\functional(278): error C2535: 'std::binder1st<_Fn2>::result_type std::binder1st<_Fn2>::operator ()(std::binder1st<_Fn2>::argument_type & ) const' : member function already defined or declared
with
[
_Fn2=std::mem_fun1_t<std::string,ResolverCommunicator,ResolverReply &>
]
c:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\functional(272) : see declaration of 'std::binder1st<_Fn2>::operator`()''
with
[
_Fn2=std::mem_fun1_t<std::string,ResolverCommunicator,ResolverReply &>
]
Run Code Online (Sandbox Code Playgroud)
然后我只是传递call_back给在另一个线程上调用的静态函数。
有人知道出了什么问题吗?
编辑:
我已经按照答案做了,但是现在我收到了这个错误:
error C2665: 'boost::bind' : none of the 3 overloads can convert …Run Code Online (Sandbox Code Playgroud) 我有以下代码,其中Boost.Local使用函数回调来加载mo文件.这个函数对我来说叫做findMo,我试图将它绑定到一个对象,这样我就可以保留我放在moFinder的私有成员中的副作用.
class moFinder
{
public:
moFinder(string const& wantedFormat)
: format(wantedFormat)
{
// ...
}
std::vector<char> findMo(std::string const& filePath, std::string const& encoding)
{
// ...
}
};
std::locale createLocale(string const& name, string const& customTranslation,
string const& path, string const& domain, string const& pathFormat)
{
// ...
namespace blg = boost::locale::gnu_gettext;
blg::messages_info info;
info.paths.push_back(path);
info.domains.push_back(blg::messages_info::domain(domain));
moFinder finder(pathFormat);
blg::messages_info::callback_type callbackFunc;
callbackFunc = boost::bind(moFinder::findMo, boost::ref(finder));
info.callback = callbackFunc;
// ...
}
Run Code Online (Sandbox Code Playgroud)
编译时我收到以下错误:
错误:无效使用非静态成员函数'std :: vector moFinder :: findMo(const std :: string&,const std :: string&)' …
当我尝试将一个function1分配给另一个function1时,Boost :: function会抛出十次异常.
任务是一个typedef boost::function1<void, void*>.
这是具体的代码:
// the Task object sent in as Task task
void Sleeper(void* arg)
{
int32_t sleepTime = *(int32_t*)arg;
SleepCurrentThread((int32_t)sleepTime);
}
struct ThreadInfo
{
ThreadInfo() : mState(DETACHED), mTask(NULL), mArg(NULL)
{ }
ThreadState mState;
Task mTask;
void* mArg;
};
Thread::Thread(Task task, void* arg, IMemoryAllocator& allocator, ILogManager& logger) : mAllocator(allocator), mLogger(logger)
{
mThreadInfo = (ThreadInfo*) mAllocator.Allocate(sizeof(ThreadInfo)); // simnple heap allocation
mThreadInfo->mArg = arg;
mThreadInfo->mState = Thread::RUNNING;
mThreadInfo->mTask = task; //<--------- throws... sometimes
mHandle = _CreateThread(&Run, (void*)mThreadInfo); …Run Code Online (Sandbox Code Playgroud) 使用boost :: function和/或boost :: bind可以简化/改进以下函数指针传递吗?
void PassPtr(int (*pt2Func)(float, std::string, std::string))
{
int result = (*pt2Func)(12, "a", "b"); // call using function pointer
cout << result << endl;
}
// execute example code
void Pass_A_Function_Pointer()
{
PassPtr(&DoIt);
}
Run Code Online (Sandbox Code Playgroud) 将a boost::function作为参数传递给另一个函数(回调)时,此函数的签名可能会变得很长.
示例:
考虑一下boost::function:
boost::function<MyClass * (
TypeA param1,
TypeB param2,
TypeC param3,
TypeD param4,
TypeE param5,
TypeF param6)> CreateMyClass;
Run Code Online (Sandbox Code Playgroud)
现在,如果我们将它boost::function作为函数参数传递,使用它的函数的签名变得非常冗长且难以阅读:
void myFunctionUsingTheCallack(boost::function<MyClass * (
TypeA param1,
TypeB param2,
TypeC param3,
TypeD param4,
TypeE param5,
TypeF param6)> the_callback);
Run Code Online (Sandbox Code Playgroud)
我在这里错过了什么吗?是否有任何缩短签名的技巧myFunctionWithTheCallack?
在调查使用boost :: bind和boost :: function将成员函数作为回调传递的可能性时,我偶然发现了一个好奇心.我正在为两个班级的模型搞错.第一个(Organism)通过int(void)函数(getAge)公开其成员变量(age).第二类(生物学家)将boost :: function存储为成员(callbackFunction)并使用它来确定(takeNotes)它正在研究的动物的当前年龄(它在成员变量m_notes中保留年龄).第二类的实例(steve_irwin)应该"观察"(takeNotes)第一类的实例(动物).
以下是实现Animal类的代码:
class Organism {
public:
Organism(int = 1);
void growOlder();
int getAge(void);
void tellAge(void);
private:
int m_age;
};
Organism::Organism(int _age) : m_age(_age) {}
void Organism::growOlder() {
m_age++;
}
int Organism::getAge(void) {
return m_age;
}
void Organism::tellAge(void) {
std::cout << "This animal is : " << m_age << " years old!";
}
Run Code Online (Sandbox Code Playgroud)
而这是实施生物学家课程的代码:
class Biologist {
public:
void setCallback(boost::function<int(void)>);
void takeNotes();
void tellAge();
private:
boost::function<int(void)> updateCallback;
int m_notes;
};
void Biologist::setCallback(boost::function<int(void)> _f) {
updateCallback …Run Code Online (Sandbox Code Playgroud) 首先是免责声明,我正在替换一堆使用boost :: function和boost :: bind的代码.但是,我正在转向不允许rtti的代码库.我想继续使用提升,但不知道是否有办法解决这个限制.
所以,我试图模仿它的一些功能,但更简化.我有一个Callback类:
template <class Class, typename ReturnType = void> class Callback0 {
typedef ReturnType (Class::*Method)();
public:
Callback0(Class* object, Method method)
: m_object(object)
, m_method(method)
{
;
}
Callback0(const Callback0& callback)
: m_object(callback.m_object)
, m_method(callback.m_method)
{
;
}
operator bool() {
return m_object != 0;
}
operator bool() const {
return m_object != 0;
}
ReturnType operator()() {
return (m_object->*m_method)();
}
Callback0<Class, ReturnType>& operator=(const Callback0<Class, ReturnType>& callback) {
if(this != &callback) {
m_object = callback.m_object;
m_method = …Run Code Online (Sandbox Code Playgroud) boost-function ×10
c++ ×9
boost ×6
boost-bind ×6
callback ×3
functor ×2
c++98 ×1
pointers ×1
virtual ×1