使用boost获得函数指针,当空指针::功能::目标 [英] null pointer when getting function pointer using boost::function::target

查看:152
本文介绍了使用boost获得函数指针,当空指针::功能::目标的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在阅读这个答案我以为我有一个解决方案。至少回答有,我想做些什么,但我有与执行问题。

After reading this answer I thought I had a solution. At least the answer there is what I would like to do but I'm having a problem with the implementation.

这里是什么,我试图做一个大纲

here is an outline of what I am trying to do

typedef map<string, double*> myMap;
typedef int (*ftwpt)(const char*, const struct stat*, int);
typedef boost::function<int(const char*, const struct stat*, int)> MyFTWFunction;

int myFunction(const char*, const struct stat*, int, myMap*);

int main()
{
myMap m_map;
char tmpdir[] = "/tmp/mytmp";

MyFTWFunction f = boost::bind(myFunction,_1,_2,_3, &m_map);

ftwpt* fpt = f.target<ftwpt>();
if (fpt)
    status = ftw(tmpdir, *fpt, 50);
else
{
    cout << "Boost could not perform runtime conversion on function pointer" << endl;
    return (EXIT_FAILURE);
}
}

该程序没有错误或警告编译,但我得到一个空指针(FPT)从f.target()返回的;在运行时。从上面的计算器问题链接引用似乎如果提升是无法执行运行时转换,则返回一个空指针。但我不知道为什么升压可能不能执行运行时转换。任何想法?

the program compiles with no errors or warnings but I am getting a null pointer (fpt) returned from f.target(); at runtime. From references linked on the above stackoverflow question it seems a null pointer is returned if boost is unable to perform the runtime conversion. But I have no idea why Boost might not be able to perform the runtime conversion. Any ideas?

推荐答案

有关的工作,你需要知道你存储到提振绑定前pression的确切类型::功能对象。对象的boost ::绑定(....)返回的是一些奇怪的EX pression模板,而不是一个函数指针。

For that to work, you would need to know the exact type of the bind expression that you store into the boost::function object. The object boost::bind(....) returns is some weird expression template, not a function pointer.

要理解为什么这是需要考虑的功能是如何提高::原则实施

To understand why this is needed, consider how boost::function is implemented in principle

struct base { virtual ~base() { } };

template<typename T>
struct derived : base {
  derived(T t):t(t) { }
  T t;
};

struct function {
  template<typename T>
  function(T t) {
    base *b = new derived<T>(t);
  }

  template<typename T>
  T *target() {
    if(typeid(*b) == typeid(derived<T>))
      return &static_cast< derived<T>* >(b)->t;
    return 0;
  }

  base *b;
};

这是最根本的结构,而不运算符()膨胀 - 很像的boost ::任何。该机制被称为类型擦除:的构造函数接受任意类型的对象,然后存储封装到一个对象,你可以通过虚拟函数调用(的boost ::功能优化像地狱,利用自身的vtable和堆栈分配,以避免小型类型等)。

That's the most fundamental structure, without the operator() bloat - much like boost::any. The mechanism is called type-erasure: The constructor accepts objects of arbitrary types, and then stores an object encapsulated into an object that you may reach through virtual function calls (boost::function is optimized like hell, using its own vtable and stack-allocation to avoid new for small types and so on).

有关函数指针,这个工程很大,因为你知道你分配给的boost ::功能目标函数的类型。但对于复杂的可调用对象,但这行不通了。

For function pointers, this works great, because you know the type of the function that you assign to the boost::function object. But for complex callable objects, it doesn't quite work anymore.

要能够看到它的工作,并看到它只是函数指针不工作,也与前结合pressions,请考虑以下code

To be able to see it working and to see that it's not just working with function pointers, but also with bind expressions, consider the following code

template<typename T>
struct id { typedef T type; };

template<typename T>
id<T> make_id(T) { return id<T>(); }

struct any_type {
  template<typename T>
  operator id<T>() const { return id<T>(); }
};

template<typename T, typename Fn>
T *get_target(boost::function<Fn> &f, id<T>)
{ return f.template target<T>(); }

void f(int a, int b) { std::cout << a << " " << b << std::endl; }

int main() {
  boost::function<void(int)> g = boost::bind(&f, _1, 10);
  (*get_target(g, true ? any_type() : make_id(boost::bind(&f, _1, 10))))(2);
}

get_target 你知道什么的boost ::绑定收益类型。你可以用它来调用目标调用并返回的包裹的boost ::函数内的对象。在然后我们调用bind前pression。请阅读埃里克Niebler的文章无条件爱来看看如何code段工程。

Within get_target you know the type of what boost::bind returns. You can use that to call the target call and return the object that's wrapped inside the boost::function. Within main we then call the bind expression. Please read Eric Niebler's article Conditional Love to see how this code snippet works.

这篇关于使用boost获得函数指针,当空指针::功能::目标的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆