Search code examples
c++parameter-passingheap-memoryrcpparmadillo

Returning an instance of a class allocated on the heap (C++)


The program I'm presently working on is written like a script with the exception of 1 class that I'm using (or attempting to) to associate 3 variables with each other. I have a class called "SupNetModel" which holds the 3 different values, no class methods. This class is declared as a header file as there aren't really any methods to implement for it.

#ifndef SUPNETMODEL_H
#define SUPNETMODEL_H

class SupNetModel {
    public:
        //variables
        SupNetModel();
};
#endif

A condensed version of my main function looks like:

#include "train.h"
#include "SupNetModel.h"
int main() {
    //Some stuff
    SupNetModel* model = Train(data,labels);
    return 1;
}

Train.cpp looks as follows

#include "train.h"
SupNetModel* Train(arma::mat data,  arma::mat labels) {
    SupNetModel * model = new SupNetModel();
    //Do a bunch of stuff
    return model;
}

EDIT: Train.h looks like:

#ifndef TRAIN_H
#define TRAIN_H

#include <RcppArmadillo.h>
#include "SupNetModel.h"

SupNetModel* Train(arma::mat data, arma::mat labels);
#endif

So essentially what I'm trying to do is create an instance of my class on the heap and then return the pointer to that instance so that I can have access to it in main. However, presently I get the following error "'SupNetModel' does not name a Type"

If it's relevant, this is being build using RCpp in an R environment. The error line that the error references is in RcppExports.cpp which is automatically generated. Upon perusal of that file (which holds information about the classes), it doesn't appear that SupNetModel is showing up in RcppExports except in the line for Train's function declaration.

EDIT: Here is the portion of the RCppExports file that is relevant:

// train
SupNetModel* train(arma::mat data, arma::mat labels);
RcppExport SEXP SupervisedNetworks_train(SEXP dataSEXP, SEXP labelsSEXP) {
BEGIN_RCPP
    SEXP __sexp_result;
    {
        Rcpp::RNGScope __rngScope;
        Rcpp::traits::input_parameter< arma::mat >::type data(dataSEXP );
        Rcpp::traits::input_parameter< arma::mat >::type labels(labelsSEXP );
        SupNetModel* __result = trainNetworkOfNetworks(data, labels);
        PROTECT(__sexp_result = Rcpp::wrap(__result));
    }
    UNPROTECT(1);
    return __sexp_result;
END_RCPP

}

And here are the last several lines that occur when I attempt to build the project:

g++ -I/usr/share/R/include -DNDEBUG -I"/home/anne/LabWork/qpOASES-3.0.0/include" -std=c++11   -I"/usr/local/lib/R/site-library/Rcpp/include" -I"/home/anne/R/x86_64-pc-linux-gnu-library/3.1/RcppArmadillo/include"   -fpic  -O3 -pipe  -g  -c LS_LocalLaplacian.cpp -o LS_LocalLaplacian.o
g++ -I/usr/share/R/include -DNDEBUG -I"/home/anne/LabWork/qpOASES-3.0.0/include" -std=c++11   -I"/usr/local/lib/R/site-library/Rcpp/include" -I"/home/anne/R/x86_64-pc-linux-gnu-library/3.1/RcppArmadillo/include"   -fpic  -O3 -pipe  -g  -c RcppExports.cpp -o RcppExports.o
RcppExports.cpp:241:1: error: ‘SupNetModel’ does not name a type
 SupNetModel* train(arma::mat data, arma::mat labels);
 ^
RcppExports.cpp: In function ‘SEXPREC* SupervisedNetworks_train(SEXP, SEXP)’:
RcppExports.cpp:249:9: error: ‘SupNetModel’ was not declared in this scope
     SupNetModel* __result = train(data, labels);
         ^
RcppExports.cpp:249:22: error: ‘__result’ was not declared in this scope
     SupNetModel* __result = train(data, labels);
                  ^
RcppExports.cpp:249:68: error: ‘train’ was not declared in this scope
     SupNetModel* __result = train(data, labels);
                                                                ^
make: *** [RcppExports.o] Error 1
ERROR: compilation failed for package ‘SupervisedNetworks’
* removing ‘/home/anne/R/x86_64-pc-linux-gnu-library/3.1/SupervisedNetworks’
* restoring previous ‘/home/anne/R/x86_64-pc-linux-gnu-library/3.1/SupervisedNetworks’

Exited with status 1.

What's causing this error, and how do you think it can be resolved?


Solution

  • Looks like the solution was quite simple.

    Left over from testing the train() function, I had left the //[[Rcpp::export]] tag above the train function which allows train() to be accessible by R. Removing this dealt with the error!