【问题标题】:Passing boost::any to results of boost::bind将 boost::any 传递给 boost::bind 的结果
【发布时间】:2008-11-20 19:33:27
【问题描述】:

我正在研究如何编写这个函数:

template <typename Bound>
Bound::result_type callFromAnyList(Bound b, list<any> p)
{
}

那么,如果我有一些功能:

double myFunc(string s, int i)
{
    return -3.0;
}

我可以通过这样做来调用它:

list<any> p;
p.push_back((string)"Hello");
p.push_back(7);
double result = callFromAnyList(bind(myFunc, _1, _2), p);

是否可以编写类似于我的callFromAnyList 函数的东西?你能从bind返回的类型中检查结果类型和参数类型吗?然后拨打any_cast&lt;P1&gt;(*p.begin())等?我试图理解绑定代码,但它有点难以理解,而且看起来他们编写它时并没有考虑到检查。

【问题讨论】:

  • 我不确定我是否理解您的意图。您希望 callFromAnyList 采用 (1) 一个函数和 (2) 一个参数列表,然后使用该参数列表以类型安全的方式调用该函数?
  • 没错。我知道这是一个奇怪的请求,但我想如果有人想出答案,我会学到很多关于 boost::bind 的内容。
  • 我认为您的请求完全有效。前段时间我尝试了您要尝试的方法,但未能找到方法。 boost::bind 有一个访问者界面,它会用参数类型和值(如果有的话)给你回电。但我还没有找到一种方法来获取参数类型-.-
  • 更清楚一点 - 在这种情况下,我并不真正关心 boost::bind。我真正关心的是检查函数的参数类型。有没有不同的方法——提升或不提升——来做到这一点?似乎 boost::bind 只是持有者,所有的聪明都在 bind 的 operator() 中。

标签: c++ boost


【解决方案1】:

当您在评论部分更新您的疑虑时,这里就是答案。仅获取函数的返回类型是可能的:

template<typename>
struct return_of;

template<typename R>
struct return_of<R(*)()> {
    typedef R type;
};

template<typename R, typename P1>
struct return_of<R(*)(P1)> {
    typedef R type;
    typedef P1 parameter_1;
};

void foo(int);

template<typename Func>
typename return_of<Func>::parameter_1 bar(Func f) {
    return 42;
}

// call: bar(foo);

我猜你明白这是怎么回事了 :) 你可以使用已经解决的 boost 函数类型:http://www.boost.org/doc/libs/1_37_0/libs/function_types/doc/html/index.html

【讨论】:

    【解决方案2】:

    我现在就这样做了 -

    void invoke(void (f)(), list<any>& params)
    {
        f();
    }
    
    template <typename R>
    void invoke(R (f)(), list<any>& params)
    {
        params.push_front(f());
    }
    
    template <typename T0>
    void invoke(void (f)(T0), list<any>& params)
    {
        T0 t0 = any_cast<T0>(*params.begin()); params.pop_front();
        f(t0);
    }
    
    template <typename R, typename T0>
    void invoke(R (f)(T0), list<any>& params)
    {
        T0 t0 = any_cast<T0>(*params.begin()); params.pop_front();
        params.push_front(f(t0));
    }
    
    template <typename T0, typename T1>
    void invoke(void (f)(T0, T1), list<any>& params)
    {
        T0 t0 = any_cast<T0>(*params.begin()); params.pop_front();
        T1 t1 = any_cast<T1>(*params.begin()); params.pop_front();
        f(t0, t1);
    }
    
    template <typename R, typename T0, typename T1>
    void invoke(R (f)(T0, T1), list<any>& params)
    {
        T0 t0 = any_cast<T0>(*params.begin()); params.pop_front();
        T1 t1 = any_cast<T1>(*params.begin()); params.pop_front();
        params.push_front(f(t0, t1));
    }
    
    template <typename T0, typename T1, typename T2>
    void invoke(void (f)(T0, T1, T2), list<any>& params)
    {
        T0 t0 = any_cast<T0>(*params.begin()); params.pop_front();
        T1 t1 = any_cast<T1>(*params.begin()); params.pop_front();
        T2 t2 = any_cast<T2>(*params.begin()); params.pop_front();
        f(t0, t1, t2);
    }
    
    template <typename R, typename T0, typename T1, typename T2>
    void invoke(R (f)(T0, T1, T2), list<any>& params)
    {
        T0 t0 = any_cast<T0>(*params.begin()); params.pop_front();
        T1 t1 = any_cast<T1>(*params.begin()); params.pop_front();
        T2 t2 = any_cast<T2>(*params.begin()); params.pop_front();
        params.push_front(f(t0, t1, t2));
    }
    

    我缺乏 boost::bind 的全部功能——比如,我无法处理方法指针——但我也意识到通过这样做,我得到了一个堆栈处理器。我可以继续调用对堆栈上的参数进行操作的方法。

    【讨论】:

      猜你喜欢
      • 2014-06-11
      • 2015-05-03
      • 2011-04-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-19
      相关资源
      最近更新 更多