boost :: function FAQ第3项专门针对我感兴趣的场景:
为什么返回void会有变通方法?C++允许他们!C++标准允许Void返回,如下面的代码片段所示:
Run Code Online (Sandbox Code Playgroud)void f(); void g() { return f(); }这是boost :: function的有效用法,因为不使用void返回.使用void返回时,我们将尝试编译类似于以下内容的格式错误的代码:
Run Code Online (Sandbox Code Playgroud)int f(); void g() { return f(); }本质上,不使用void返回允许boost :: function吞下返回值.这与允许用户使用不完全匹配的参数分配和调用函数和函数对象是一致的.
不幸的是,这在VS2008中不起作用:
int Foo();
std::tr1::function<void()> Bar = Foo;
Run Code Online (Sandbox Code Playgroud)
这会产生以下错误:
c:\Program Files\Microsoft Visual Studio 9.0\VC\include\xxcallfun(7) : error C2562: 'std::tr1::_Callable_fun<_Ty>::_ApplyX' : 'void' function returning a value
Run Code Online (Sandbox Code Playgroud)
这是VS2008 TR1实现的失败吗?这在VS2010中有效吗?TR1是否解决了这种能力?C++ 0x怎么样?
我正在浏览Boost中的"Function"类文档,并偶然发现:
boost::function<float (int x, int y)> f;
Run Code Online (Sandbox Code Playgroud)
我必须承认这种语法对我来说非常困惑.这怎么可能是合法的C++?
引擎盖下有什么伎俩吗?这种语法记录在何处?
我有一个类似下面的工人类:
class Worker{
public:
int Do(){
int ret = 100;
// do stuff
return ret;
}
}
Run Code Online (Sandbox Code Playgroud)
它的目的是使用boost :: thread和boost :: bind来执行,如:
Worker worker;
boost::function<int()> th_func = boost::bind(&Worker::Do, &worker);
boost::thread th(th_func);
th.join();
Run Code Online (Sandbox Code Playgroud)
我的问题是,如何获得Worker :: Do的返回值?
提前致谢.
我正在为动态加载的库实现一个独立于平台的包装器.当然,当我从库中加载函数时,我需要将它们存储为指针以供将来使用.我想过使用boost :: function来代替普通的函数指针.当然,这会增加编译时间,但这不是我所害怕的.而是:
调用存储函数时boost :: function引入的开销是多少?有吗?它有多大?
我想在不时调用这些函数时我不会有太大的开销,但是,那些被调用的函数怎么样?(极端的例子,glVertex在加载的GL库上).它对性能有多大影响?
源头潜水提升没有多少回答:>.
此外,如果它依赖于编译器,我主要对GCC和MSVC感兴趣.
我正在设置一个成员函数作为我正在使用的C库的回调.C库设置如下的回调:
typedef int (*functionPointer_t)(myType1_t*, myType2_t*, myType3_t*);
setCallback(param1, param2, functionPointer, param4)
Run Code Online (Sandbox Code Playgroud)
我想使用boost :: bind(如果可能的话)传入函数指针.我希望指向的函数是实例化类的成员,而不是静态成员.例如
Class A {
public:
A();
protected:
int myCallback(myType1_t*, myType2_t*, myType3_t*); //aka functionPointer_t
}
Run Code Online (Sandbox Code Playgroud)
可以使用boost :: bind和boost :: function来完成吗?Per 如何将类成员函数作为回调传递?(第3个答案)似乎我可以声明以下内容(某处或作为typedef):
boost::function<int (A*, myType1_t*, myType2_t*, myType3*> myCallbackFunction
Run Code Online (Sandbox Code Playgroud)
然后在A(ctor)的某处调用boost :: bind在该类型上,并将其传递给C库调用.
这可能吗,还是我不在基地?非常感谢.
#include <QtCore/QCoreApplication>
#include <boost/bind.hpp>
#include <boost/function.hpp>
class button
{
public:
boost::function<void()> onClick;
boost::function<void(int ,double )> onClick2;
};
class player
{
public:
void play(int i,double o){}
void stop(){}
};
button playButton, stopButton;
player thePlayer;
void connect()
{
//error C2298: 'return' : illegal operation on pointer to member function expression
playButton.onClick2 = boost::bind(&player::play, &thePlayer);
stopButton.onClick = boost::bind(&player::stop, &thePlayer);
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
connect();
return a.exec();
}
Run Code Online (Sandbox Code Playgroud) 我有一个可能非常简单的问题:在类中传递并调用成员函数.我知道我想使用BOOST绑定(和/或函数),但我还没有真正掌握它的概念.
以下代码编译并执行问题.但是当我想将"f3"函数更改为非静态类函数时,乐趣就开始了:
#include <iostream>
#include <inttypes.h>
#include <boost/bind.hpp>
#include <boost/function.hpp>
class Test
{
public:
void f1();
private:
void f2(void (*callfunc)(uint32_t));
static void f3(uint32_t x);
};
void Test::f1(){
f2(f3);
}
void Test::f2(void (*callfunc)(uint32_t)){
(*callfunc)(42);
}
void Test::f3(uint32_t x){
std::cout << "x: " << x << std::endl;
}
int main(int argc, char ** argv)
{
Test ct;
ct.f1();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
现在,改变之后
static void f3(uint32_t x);
Run Code Online (Sandbox Code Playgroud)
至
void f3(uint32_t x);
Run Code Online (Sandbox Code Playgroud)
编译器不满意并告诉我"错误:没有匹配函数调用'Test :: f2()'"
阅读了一些关于boost :: bind和boost :: function的SO帖子,我想我需要改变f2()的定义以及f1()如何调用f2()给f3()作为调用目标,但是除此之外......关于boost :: bind和boost函数的每个组合,我都试过很难编译.
我该如何写这个?作为一个额外的问题:是否有关于boost :: …
假设我已经分配了堆A*,我希望将其作为参数传递给boost::bind.
boost::bind保存以供稍后处理某些STL的容器boost::functions.
我想确保A*在销毁STL容器时销毁.
示范:
A* pA = new A();
// some time later
container.push_back(boost::bind(&SomeClass::HandleA, this, pA);
// some time later
container is destroyed => pA is destroyed too
Run Code Online (Sandbox Code Playgroud)
怎么做到呢?
编辑
也许我想要的不是那么现实.
我有原始指针和函数接收原始指针.通过boost :: bind延迟调用.此时我想要自动内存管理,以防boost :: bind想要执行.我很懒,所以我想使用"准备好"的智能指针解决方案.
std :: auto_ptr看起来像个好人,但是......
auto_ptr<A> pAutoA(pA);
container.push_back(boost::bind(&SomeClass::HandleA, this, pAutoA);
Run Code Online (Sandbox Code Playgroud)
不编译(见这里)
auto_ptr<A> pAutoA(pA);
container.push_back(boost::bind(&SomeClass::HandleA, this, boost::ref(pAutoA));
Run Code Online (Sandbox Code Playgroud)
pAutoA被破坏,删除了底层的pA.
编辑02
在上面提到的容器中,我将需要使用不同的参数存储misc"回调".其中一些是对象的原始指针.由于代码是旧的,我并不总是可以改变它.
编写自己的包装器来存储容器中的回调是最后的手段(可能是唯一的),因此是赏金.
我需要将距离函数传递给模板.因此我使用boost :: function和boost :: bind.但我不明白我必须通过课程距离:
template<class DataType, class Point, class Distance>
class CoverTree
{
Distance distance;
...
public:
CoverTree(const Distance& distance) : max_level(default_max_level), min_level(default_max_level), distance(distance) {}
...
}
Run Code Online (Sandbox Code Playgroud)
模板作者的示例如下所示:
float euclidian(const std::vector<float>& p1, const std::vector<float>& p2)
{
...
}
int main(int argc, char** argv)
{
CoverTree<float, std::vector<float>, float (*const)(const std::vector<float>&, const std::vector<float>&)> tree(&euclidian);
...
}
Run Code Online (Sandbox Code Playgroud)
现在这是我的主要内容:
int main(int argc, char** argv)
{
AllData myData;
boost::function<float (const vector<Frame>::const_iterator&, const vector<Frame>::const_iterator&)> j_dist;
j_dist = boost::bind(&AllData::jaccard_distance, myData, _1, _2);
myData.AddData("C:\\...");
cout<<j_dist(myData.DATAx.begin()+20, …Run Code Online (Sandbox Code Playgroud) 问题出在标题中.我在参考文档中找不到相关信息.我不明白为什么默认构造函数会抛出,但我需要确保它是无法正确记录我的异常保证.
boost-function ×10
c++ ×10
boost ×7
boost-bind ×6
c++11 ×2
auto-ptr ×1
boost-thread ×1
exception ×1
functor ×1
templates ×1
tr1 ×1