C++ 为什么Rcpp::函数可以用作boost::函数,并且可以在运行时对其进行内省?

C++ 为什么Rcpp::函数可以用作boost::函数,并且可以在运行时对其进行内省?,c++,r,boost,rcpp,C++,R,Boost,Rcpp,我有一个向量——本质上是一个函数类对象的向量。向量包含一些Rcpp::Function对象,以及一些boost::Function对象 我有两个问题。首先,我不太明白它是如何工作的,因为据我所知,Rcpp::Function不是boost::Function的子类。向量如何存储这些不具有相同类的对象?(或者他们是否以某种方式共享一个课程?) 第二,也是更重要的一点,我希望能够在运行时内省对象。我想迭代向量并返回它的Rcpp::List表示:任何Rcpp::Function对象都将添加到列表中,任

我有一个
向量
——本质上是一个函数类对象的向量。向量包含一些
Rcpp::Function
对象,以及一些
boost::Function
对象

我有两个问题。首先,我不太明白它是如何工作的,因为据我所知,
Rcpp::Function
不是
boost::Function
的子类。向量如何存储这些不具有相同类的对象?(或者他们是否以某种方式共享一个课程?)

第二,也是更重要的一点,我希望能够在运行时内省对象。我想迭代向量并返回它的
Rcpp::List
表示:任何
Rcpp::Function
对象都将添加到列表中,任何
boost::Function
对象都将简单地用任意字符串表示,如
“C++函数”

在下面的例子中,我有一个C++函数Test< /Cord>,它以<代码> RCPP::函数< /C>作为输入并添加到vector中。它还向向量添加了一个

boost::function
。然后它在列表上迭代,执行每个函数。最后一部分,我还没有弄清楚,是如何构建一个
列表
,其中添加到列表中的项目取决于每个项目的类型。这可能吗

library(Rcpp)

cppFunction(
  includes = '
    #include <boost/function.hpp>
    #include <boost/bind.hpp>
    #include <iostream>

    void cpp_message(std::string s) {
      std::cerr << s << "\\n";
    }
  ',
  code = '
    Rcpp::List test(Rcpp::Function r_fn) {
      std::vector<boost::function0<void> > fns;

      // Add a Rcpp::Function to the vector
      fns.push_back(r_fn);

      // Add a boost::function<void(void)> to the vector
      boost::function<void(void)> cpp_fn = boost::bind(&cpp_message, "bar");
      fns.push_back(cpp_fn);

      // Execute the functions to demonstrate the vector works
      for (int i=0; i<fns.size(); i++) {
        fns[i]();
      }

      // Create the List       
      Rcpp::List result;
      for (int i=0; i<fns.size(); i++) {
        // What I would like to do is something like:
        // if (fns[i] is a Rcpp::Function) {
        //   result[i] = fns[i];
        // } else {
        //   result[i] = "C++ function";
        // }
      }

      return result;
    }
  ',
  depends = "BH"
)

test(function() message("foo"))
#> foo
#> bar
#> list()
库(Rcpp)
cpp函数(
包括:
#包括
#包括
#包括
无效cpp_消息(标准::字符串s){
标准:cerr
向量如何存储这些不具有相同类的对象

嗯,不是向量(直接)存储这样的对象,而是向量中新创建的
boost::function
对象将存储实例。这个对象将如何存储实例

一些简单的演示类说明了如何实现这一点:

// first need a generic template allowing the Demo<void(void)> syntax
template <typename S>
class Demo;

// now specialising (otherwise, we'd need to instantiate Demo<void, void>)
template <typename R, typename ... PP>
class Demo<R(PP...)>
{
    class Wrapper
    {
    public:
        virtual ~Wrapper() { }
        virtual R operator()(PP...) = 0;
    };

    template <typename T>
    class SpecificWrapper : public Wrapper
    {
        T t;
    public:
        SpecificWrapper(T& t) : t(t) { };
        virtual R operator()(PP...pp) { return t(pp...); }
    };

    // the trick: pointer to POLYMORPHIC type!
    Wrapper* w;

public:
    // be aware that this constructor deliberately is NOT explicit
    template <typename T>
    Demo(T& t) : w(new SpecificWrapper<T>(t)) { }

    R operator()(PP...pp) { return (*w)(pp...); }
};
//首先需要一个允许演示语法的通用模板
模板
课堂演示;
//现在专业化(否则,我们需要实例化演示)
模板
课堂演示
{
类包装器
{
公众:
虚拟~Wrapper(){}
虚拟R运算符()(PP..)=0;
};
模板
类SpecificWrapper:公共包装器
{
T;
公众:
特殊包装(T&T):T(T){};
虚拟R运算符()(PP…PP){返回t(PP…;}
};
//诀窍:指向多态类型的指针!
包装纸*w;
公众:
//请注意,此构造函数不是显式的
模板
演示(T&T):w(新的SpecificWrapper(T)){}
R运算符()(PP…PP){return(*w)(PP…);}
};
非显式构造函数允许隐式创建新的演示对象:

Rcpp::Function r; // simplified just for demo!
std::vector<Demo<void(void)>> v;
v.push_back(r);   // implicit call to non-explicit constructor! equivalent to:
v.push_back(Demo<void(void)>(r));
Rcpp::Function r;//仅为演示而简化!
std::向量v;
v、 push_back(r);//隐式调用非显式构造函数!等价于:
v、 推回(演示(r));
请注意,该类的实现非常简单(可能只添加了复制构造函数、移动构造函数和适当的赋值运算符),因为它仅用于演示目的

我希望能够在运行时内省对象

您正在寻找:


auto l=[](){std::cout谢谢这非常有用。我之所以要这样做,不是为了通用,而是为了帮助调试。
auto l = []() { std::cout << "demo" << std::endl; };
std::function<void(void)> f(l);
auto* pl = f.target<decltype(l)>();
if(pl)
    (*pl)();