I'm Creating a class that I want to call a recursive function within it. However, the complier says i cant declare a function within a method, I was wondering how I could Recursively call that function, in the method, or how to recursively call that method, with out declaring the function out of the class;

#include <iostream>
#include <vector>
#include <math.h>
#include <cstring>

using namespace std;




class RMatrix
{
    int sizeH;
    int sizeL;
    int TotalN, Replace;
protected:
    bool ** Matrix;
    RMatrix(int, int);
    ~RMatrix(){for (int x = 0; x<sizeH; x++)delete [] Matrix[x]; delete [] Matrix;}
    void DisplayMx ();
    void RepMatrixf();
};

RMatrix::RMatrix(int TND, int NRep)
{
    TotalN=sizeL=TND;
    Replace=NRep;
    int PrevResult = TND;                               // previous result will equal
    for (int C = 1; C<NRep; C++)                        // iterates through each cell
     {
      PrevResult= (PrevResult*(TND-1))/(C+1);          // changes previous result based on pascal formula
      TND--;                                           // subtracts from row
     }
     sizeH = PrevResult;
     Matrix = new bool *[PrevResult];                  // dynamic allocation array by pointer
     for (int z = 0; z < PrevResult; z++)
       {
        Matrix[z] = new bool[TND];                     // assign dynamically array
       }
}

void RMatrix::RepMatrixf()
{
     const int MAX = 100;   // PROBLEM STARTS BELOW
     void RepMatrix (int NDR, int size, int PosIR, int calls) // PosIR and calls initates at 0
      {
        if (calls==0)
            memset(Matrix, 0, sizeof(Matrix));     // clears previous values of matrix **note memset only can set values for 0 or -1 in ints
        static int Row = 0;                        // Row, stored for recursion
        static int RepIndex[MAX];                  // stores positions of variable to be turned true
         for ( ; PosIR < size-(NDR-1); PosIR++)     // Position index Replacement is less than number of digits being replaced
          {                                         // Increase of each possible combination index
            RepIndex[calls]=PosIR;                 // sets the replacement value for static array based of which call

          if (NDR==1)                              // NDR is last digit
           {
              for (int x = 0; x<=calls; x++)       // all possible replacement permutation are changed to false
               {
                 Matrix[Row][RepIndex[x]]=true;
               }
              Row++;                                // row is increased
           }
           if (NDR>1)                             // recursively calls for ever digit in need of being replaced
           {
             RepMatrix((NDR-1), size, PosIR+1, calls+1);
           }
          }
        return;
      }
     RepMatrix(Replace, TotalN, 0, 0);

}

void RMatrix::DisplayMx()
{
    for (int x = 0; x < sizeH; x++)
     {
        for (int y = 0; y<sizeL; y++ )
         {
            cout << Matrix[x][y] << " ";
         }
        cout << endl;
     }
}

int main ()
{
    RMatrix T(5, 2);
    T.DisplayMx();
    return 0;
}

Recommended Answers

All 8 Replies

Embedded it inside an internal struct. Not sure if you can use lambda functions here but meh I prefer the internal struct.

void RMatrix::RepMatrixf()
{
    const int MAX = 100;   // PROBLEM STARTS BELOW
    struct
    {
        void RepMatrix (int NDR, int size, int PosIR, int calls) // PosIR and calls initates at 0
        {
            if (calls == 0)
                memset(Matrix, 0, sizeof(Matrix));     // clears previous values of matrix **note memset only can set values for 0 or -1 in ints
            static int Row = 0;                        // Row, stored for recursion
            static int RepIndex[MAX];                  // stores positions of variable to be turned true
            for ( ; PosIR < size-(NDR-1); PosIR++)     // Position index Replacement is less than number of digits being replaced
            {
                // Increase of each possible combination index
                RepIndex[calls]=PosIR;                 // sets the replacement value for static array based of which call

                if (NDR==1)                              // NDR is last digit
                {
                    for (int x = 0; x<=calls; x++)       // all possible replacement permutation are changed to false
                    {
                        Matrix[Row][RepIndex[x]]=true;
                    }
                    Row++;                                // row is increased
                }
                if (NDR>1)                             // recursively calls for ever digit in need of being replaced
                {
                    RepMatrix((NDR-1), size, PosIR+1, calls+1);
                }
            }
            return;
        }
    } Inner;

    Inner.RepMatrix(Replace, TotalN, 0, 0);
}

I Tried your solution but that makes my complier explode, "Invalid use of nonstatic datamember and then it puts errors for the rest of the class as well

Well, line 42 and 45 you're trying to declare a function in another function, and that's not allowed.

  void RMatrix::RepMatrixf()
  {
       const int MAX = 100;   // PROBLEM STARTS BELOW
       void RepMatrix (int NDR, int size, int PosIR, int calls)

but by looking to your code, you want to do something that is quite impossible. You see, in C++ functions can be overloaded, meaning that you can have

void f(){
    cout<"hi";
}

and 

void f(int a){
    cout<<"hi";
}

but that doesn't mean that f is the same, instead they are looked as different functions, and they are different functions. So in your case, you can't call RepMatrixf() with no parameters as RepMatrix (int NDR, int size, int PosIR, int calls) with a lot of parameters. You should get out the secon declaration of the function, the RepMatrix (int NDR, int size, int PosIR, int calls) from RepMatrix () because it's of no good. But, if you do want to call a function recursively you have to do like this:

int total=10;

void add(int &total){
    if (total==0) return;
    else {
        total--;
        add(total);
    }
}

int main(){
    add(total);
    cout<<total;
    return (0);
}

Just make the void RepMatrix funtion a provate function of the class. That way no one can use except you.

There is probably a way to make it work as a function within the function. However, this is really unusual and unnecessary. The proper solution, seconding NathanOliver on this, is to make the recursive function a private member function of your class.

Also, having those static local variables like that is a bit weird, too weird for my taste. In fact, it's a bug because if you call the same function more than once, then those static local variables will not be initialized again (will keep the values they had after all the recursions of the first call. Personally, I think you should just create a private nested class within your class to do the recursion. As so:

class RMatrix
{
    int sizeH;
    int sizeL;
    int TotalN, Replace;

    class RepMatrixCalculator {
      private:
        RMatrix* parent;
        int Row;
        int* RepIndex;
      public:
        RepMatrixCalculator(RMatrix* aParent, int MAX) : 
                            parent(aParent), 
                            Row(0),
                            RepIndex(new int[MAX]) { };
        ~RepMatrixCalculator() { delete[] RepIndex; };

        void RepMatrix(int NDR, int size, int PosIR, int calls);
    };

protected:
    bool ** Matrix;
    RMatrix(int, int);
    ~RMatrix(){for (int x = 0; x<sizeH; x++)delete [] Matrix[x]; delete [] Matrix;}
    void DisplayMx ();
    void RepMatrixf();
};


void RMatrix::RepMatrixCalculator::RepMatrix(int NDR, int size, int PosIR, int calls)
{

    if (calls==0)
        ;
        //memset(parent->Matrix, 0, sizeof(parent->Matrix));
        // NOTE: The above line of code is completely wrong.
        // NOTE2: Setting the matrix to zero probably something you could do in 
        //        the constructor of RepMatrixCalculator.
    for ( ; PosIR < size-(NDR-1); PosIR++)
    {                                       
        RepIndex[calls]=PosIR;                
        if (NDR==1)                             
        {
            for (int x = 0; x<=calls; x++)      
            {
                parent->Matrix[Row][RepIndex[x]]=true;
            }
            Row++;                              
        }
        if (NDR>1)                             
        {
            RepMatrix((NDR-1), size, PosIR+1, calls+1);
        }
    }
    return;
};

void RMatrix::RepMatrixf()
{
     const int MAX = 100;   // PROBLEM STARTS BELOW

     // Create an object of the nested class:
     RepMatrixCalculator helper_obj(this, MAX);

     // then call the recursion:
     helper_obj.RepMatrix(Replace, TotalN, 0, 0);
}

The above is a useful technique, especially for a recursion. You can put all the initialization (allocating storage for the algorithm) and the finalization (freeing that storage) in the constructor / destructor of the nested class, respectively. In your case, for example, it will negate the need for this awkward scheme of passing this calls variable just to identify the first recursion, and you can have those "static" variables needed for the recursion as data members of the helper class.

As for that line which attempts to set the matrix to zero. This is completely wrong. The sizeof() operator only returns the size (fixed) of the type of the expression (or variable) that is given to it. In this case, the type is bool** which is just a pointer type (pointer to pointer to bool) which will have a fixed size of either 4 or 8 bytes (32bit or 64bit system). This will not give you the number of elements that the matrix contains, and, in any case, using memset for this purpose is wrong. To set that matrix to zero, you will need to do an iteration over the rows and columns and set individual elements to false.

@lucaci RepMatrixf and RepMatrix are two different functions i was just too lazy to name them something different

@mike_2000_17 Thanks with the info you gave me I should be albe to get it working. The function im using in there was already created and working prior to creating a class, I dont really need to use memset anymore, because dynamic allocation initialize the bool for me. However i did research into memset before using it you can set an int array that way but it probably isnt the most proper thing to do. as for the sizeof was also from the prior function which i couldnt test in here yet because i didnt get it working

I got it working
im just confused on one part what exactly is

RepMatrixCalculator(RMatrix* aParent, int MAX) :
parent(aParent),
Row(0),
RepIndex(new int[MAX]) { };

doing, isnt the : for inheritance

That part is an initialization list, it is used to construct the data members of the class. This is the preferred method to initialize data members (as opposed to assigning values to the data members in the body of the constructor).

commented: Thanks! this is very helpful +0
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.