Rcpp Enum支持

时间:2017-10-23 18:46:36

标签: c++ r enums rcpp

我正在使用Rcpp Modules来导出类方法。其中一些方法具有枚举的返回类型。例如:

#include "Enum.h"
#include <Rcpp.h>
using namespace Rcpp;

class EnumTest{
public:
  EnumTest(){}
  void setP(Polarization pol){p = pol;}
  Polarization getP(){return p;}
private:
  Polarization p;
};

RCPP_EXPOSED_CLASS(EnumTest)
RCPP_MODULE(EnumTest){
  class_<EnumTest>("EnumTest")
  .property("p", &EnumTest::getP, &EnumTest::setP)
  ;
}

极化是一个枚举,定义如下:

enum Polarization{
  HORIZONTAL_POL = 0,
  VERTICAL_POL   = 1
};

当我尝试构建代码时,出现以下错误。

  

无法转换&#39; SEXP&#39;到极化&#39;在初始化

无论如何将枚举暴露给Rcpp,类似于如何公开类?我在Rcpp模块中注意到,enum类型列在未来的扩展中。这是否意味着没有办法做到这一点?如果是这样,有没有可能的解决方法?

2 个答案:

答案 0 :(得分:3)

由宏here给出的对Rcpp中枚举的支持有限。

所以你可以这样做:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>Hello React!</title>
    <script src="https://unpkg.com/react@15/dist/react.js"></script>
    <script src="https://unpkg.com/react-dom@15/dist/react-dom.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.23/browser.min.js"></script>
    <script src="https://www.gstatic.com/firebasejs/3.9.0/firebase.js"></script>
  </head>
  <body>
    <div id="root"></div>
    <script type="text/babel">      
        class NewCandidate extends React.Component {
            constructor(props) {
                super(props);               
            }           
            test(){
                alert("Within newCandidate");
            }   

            render(){
                return(
                  <div>
                    <table>
                        <tbody>
                        <tr>
                            <th colSpan="2">Candidate details</th>
                        </tr>
                        <tr>
                            <th>Name</th><td><input type="text" /></td> 
                        </tr>
                        <tr>
                            <th>Email</th><td><input type="text" ref="candEmail" /></td>
                        </tr>
                        <tr>
                            <th>Mobile</th>
                            <td>
                                <input type="text" />
                            </td>
                        </tr>
                        <tr>
                            <th>Gender</th>
                            <td>
                                <input type="radio" value="Male" name="gender" />Male 
                                <input type="radio" value="Female" name="gender"  />Female
                            </td>
                        </tr>
                        </tbody>
                    </table>
                  </div>
                )
            }
        }
        class Interview extends React.Component {
            constructor(props){
                super(props);
                this.state = {
                    candidates: [],
                    candidate_name: [],
                    candidate_email: [],
                    interviewer_name: '',
                    phase: ''
                }
                this.addNewCandidate = this.addNewCandidate.bind(this);             
            }           
            addNewCandidate(e) {
                e.preventDefault();
                var arr=this.state.candidate_name;
                arr.push(null);         
                var arr_email=this.state.candidate_email;
                arr_email.push(null);           
                const candidateList = [].concat(this.state.candidates);
                candidateList.push(<div key={`candidate-${candidateList.length}`}><NewCandidate indexVal={candidateList.length} handleCandidateChangeName={this.handleCandidateChangeName} handleCandidateChangeEmail={this.handleCandidateChangeEmail} handleCandidateChangeGender={this.handleCandidateChangeGender} ref="child" /></div>)
                this.setState({candidates: candidateList});
            }               
            render() {
                return (
                  <div>                 
                    {this.state.candidates}             
                    <button type="button" onClick={this.addNewCandidate} >Add New Candidate</button>
                    <button type="button" onClick={this.refs.child.refs.test}>Save</button>             
                  </div>
                )
              }
        }
        // render Interview component
        ReactDOM.render(<Interview />,document.getElementById("root"));
</script>
  </body>
</html>

支持是非常基本的,基本上允许您将枚举作为整数传递,丢失类和一切。有时它足够了。我建议在R端有一个简单的命名列表,以使代码更清晰,例如

#include <Rcpp.h>
using namespace Rcpp; 

enum Polarization{
  HORIZONTAL_POL = 0,
  VERTICAL_POL   = 1
};

RCPP_EXPOSED_ENUM_NODECL(Polarization)

class EnumTest{
  public:
    EnumTest(){}
  void setP(Polarization pol){p = pol;}
  Polarization getP(){return p;}
  private:
    Polarization p;
};


RCPP_MODULE(Bla){
  class_<EnumTest>("EnumTest")
    .constructor()
    .property("p", &EnumTest::getP, &EnumTest::setP)
  ;
}

这样你就可以做到

Polarization <- list( HORIZONTAL_POL = 0L, VERTICAL_POL = 1L )

答案 1 :(得分:0)

如记录所示,来自/到R的接口(我们使用/应该使用的)是

SEXP .Call(yourFunction, SEXP a, SEXP b, SEXP c, ...)

Rcpp为您的转换器提供基本类型。但是你的枚举不是这些基础之一,所以你必须编写自己的转换器,或者只传递可以通过的整数值。