Search code examples
rcpp

Understanding error messages in Rcpp code with structures and functions


I'm getting a couple of error messages when I run the following code that I do not understand -

expected initializer before 'add_f'

no matching function for call to 'try_grid::try_grid(Rcpp::NumericMatrix&, Rcpp:: NumericMatrix&, int&)

Can someone explain what I am doing incorrectly?

cpp file:

#include <Rcpp.h>

using namespace Rcpp;

//Declaring a structure
struct try_grid
{
    NumericMatrix x;
    NumericMatrix y;
    int size;
}

// Declaring function
Void add_f(const try_grid&);

// [[Rcpp::export]]
NumericMatrix plussomething(NumericMatrix samp, NumericMatrix tramp, int size)
{
    // Declaring and defining output matrix
    NumericMatrix sol(size, size);

    // Initialising members of the structure
    struct* try_grid m = {samp, tramp, size};

    // operation
    try_grid add_f(m);


    // Creating output
    for(int i=0; i<size; i++)
    {
        for(int j=0; j<size; j++)
        {
            sol(i,j) = m.x(i,j) + m.y(i, j);
        }    
    }
    
    return(sol);
}

// Defining function
try_grid add_f(NumericMatrix x, NumericMatrix y, int size)
{
   for(int i=0; i<size; i++)
    {
        for(int j=0; j<size; j++)
        {
            if(x(i,j) == 0 && y(i,j) != 0)
            {
                x(i,j) = y(i,j);
            }

            if(y(i,j) == 0 && x(i,j) != 0)
            {
                y(i,j) = x(i,j);
            }
        }    
    }

    return try_grid(x, y, size);
}

The R code:

#Creating a matrix
samp <- matrix(0, 5, 5)
samp[3,3] <- 1

tramp <- matrix(0, 5, 5)
tramp[2,2] <- 2

sss <- 5

#Accessing the Rcpp file
sourceCpp('rcppfunction.cpp')

Solution

  • You wrote Void with a capital V. That does not exist as a keyword -- use void. And the error message

    expected initializer before 'add_f'
    

    hints at that. You are also missing a semicolon after the struct declaring, use a wrong structure to initialize your try_f object (you cannot just 'assign a to a pointer') and have no constructor for the try_grid object you try to return.

    In short, you need to rework your code a little more. Maybe try in smaller steps. Below is a minimally repaited version.

    Code

    #include <Rcpp.h>
    
    using namespace Rcpp;
    
    //Declaring a structure -- with a constructor
    struct try_grid {
        try_grid(NumericMatrix x_, NumericMatrix y_, int size_) : x(x_), y(y_), size(size_) {};
        NumericMatrix x;
        NumericMatrix y;
        int size;
    };
    
    // Declaring function
    void add_f(const try_grid&);
    
    // [[Rcpp::export]]
    NumericMatrix plussomething(NumericMatrix samp, NumericMatrix tramp, int size) {
        // Declaring and defining output matrix
        NumericMatrix sol(size, size);
    
        // Initialising members of the structure
        try_grid m{samp, tramp, size};
    
        // operation
        try_grid add_f(m);
    
        // Creating output
        for(int i=0; i<size; i++)  {
            for(int j=0; j<size; j++) {
                sol(i,j) = m.x(i,j) + m.y(i, j);
            }
        }
    
        return(sol);
    }
    
    // Defining function
    try_grid add_f(NumericMatrix x, NumericMatrix y, int size) {
       for(int i=0; i<size; i++) {
            for(int j=0; j<size; j++) {
                if(x(i,j) == 0 && y(i,j) != 0) {
                    x(i,j) = y(i,j);
                }
    
                if(y(i,j) == 0 && x(i,j) != 0) {
                    y(i,j) = x(i,j);
                }
            }
        }
    
        return try_grid(x, y, size);
    }
    
    /*** R
    #Creating a matrix
    samp <- matrix(0, 5, 5)
    samp[3,3] <- 1
    
    tramp <- matrix(0, 5, 5)
    tramp[2,2] <- 2
    
    sss <- 5
    
    plussomething(samp, tramp, sss)
    */
    

    Output

    > Rcpp::sourceCpp("answer.cpp")
    
    > #Creating a matrix
    > samp <- matrix(0, 5, 5)
    
    > samp[3,3] <- 1
    
    > tramp <- matrix(0, 5, 5)
    
    > tramp[2,2] <- 2
    
    > sss <- 5
    
    > plussomething(samp, tramp, sss)
         [,1] [,2] [,3] [,4] [,5]
    [1,]    0    0    0    0    0
    [2,]    0    2    0    0    0
    [3,]    0    0    1    0    0
    [4,]    0    0    0    0    0
    [5,]    0    0    0    0    0
    > 
    

    Edit: You can also use a struct instead of a class but you need the constructor to instantiate.