1

Below is a piece of code I was trying to run where I have function I want to run (dN) within my main function which returns a value of type complex<double>.

#include <iostream>
#include <complex>
#include <cmath>
using namespace std;

const complex<double> Im1(0.0,1.0); //imaginary number definition

class Functions{
public:
    complex<double> dN(complex<double> **N, int k, int i, complex<double> kN, double T1){
        complex<double> OUT = Im1*(N[k][i]+kN)/(T1);
        return OUT;
    }; 

};

int main(int argc, const char * argv[]) {

    //...more code here

    complex<int> **NM = new complex<int>*[1000]; //1000x500 array
    //run loop to initialize
    for (int i = 0; i < 1000; ++i)
    {
        NM[i] = new complex<int>[500];
    }

    complex<double> dN_OUT = Functions::dN(**NM,1,20,0.,20.);

    return 0;
};

Although this code does not run and returns the error: Call to non-static member function without an object argument

Based on my understanding, C++ does not allow nested functions and my code above would not work because I call a separate function in my main function. Although (based on the link) it does appear one can implement "local classes" by defining a function within a struct which would have to be inside the main function. Although when I try doing that:

int main(int argc, const char * argv[]) {

    complex<int> **NM = new complex<int>*[1000]; //1000x500 array
    //run loop to initialize
    for (int i = 0; i < 1000; ++i)
    {
        NM[i] = new complex<int>[500];
    }

    struct Functions{
        complex<double> dN(complex<double> **N, int k, int i, complex<double> kN, double T1){
            complex<double> OUT = Im1*(N[k][i]+kN)/(T1);
            return OUT;
        }; 

    };

    complex<double> dN_OUT = Functions::dN(**NM,1,20,0.,20.);

    return 0;
};

the error persists. Ultimately, I am simply wanting to use the function dN that returns output of type complex<double> within my main function, but am unsure of the best/operational way to implement this.

Community
  • 1
  • 1
Mathews24
  • 681
  • 10
  • 30

3 Answers3

2

I believe you misunderstand what a nested function is. A nested function would look like this:

int main()
{
    void nested() {} // not allowed in C++
}

The solution to your problem is in the error message provided by your compiler:

Call to non-static member function without an object argument

Take a look at the following:

// Example 1
struct Functions {
   void func() {}
};

int main() 
{
   // to call Functions::func() you would need to have an object
   // of type Functions because Functions::func() is not a static function
   Functions f;
   f.func();
}

// Example 2
// by making func() static you can call it without an object:
struct Functions {
   static void func() {}
};

int main() 
{
    Functions::func(); // OK
}
DeiDei
  • 10,205
  • 6
  • 55
  • 80
  • Some *compilers* accept nested functions (as an extension to the language they handle) which are indeed not part of standard C++11. GCC accepts [nested functions](https://gcc.gnu.org/onlinedocs/gcc/Nested-Functions.htm) for C, not for C++ – Basile Starynkevitch Jan 14 '17 at 07:53
  • @BasileStarynkevitch That is true, but I can't remember the last time I compiled without the `-pedantic` flag. – DeiDei Jan 14 '17 at 07:54
  • @DeiDei Ahh yes, sorry. My initial attempt was to use a nested function as you said although I changed it to a class outside of the main function afterwards (which is the code posted above). Thank you for your answer—it appears to work although I am just testing the code at this point and will get back to you shortly. Just to clarify, why does simply adding static work? – Mathews24 Jan 14 '17 at 08:13
  • @Mathews24 *why does simply adding static work?* I explained it in the answer. Non-static member functions of a type (struct or class) need an object to be called, while static ones - don't. The error message also conforms. – DeiDei Jan 14 '17 at 08:16
2

Ultimately, I am simply wanting to use the function dN that returns output of type complex within my main function, but am unsure of the best/operational way to implement this.

Use a free function, like main is, unless dN has a specific reason to be part of a class:

complex<double> dN(complex<double> **N, int k, int i, complex<double> kN, double T1)
{
...
}

int main(int argc, const char * argv[]) {
    ...
    //like this 
    complex<double> dN_OUT = dN(NM,1,20,0.,20.);
    //not like this
    //complex<double> dN_OUT = dN(**NM,1,20,0.,20.);
}
RaspiRepo
  • 78
  • 2
chris
  • 60,560
  • 13
  • 143
  • 205
1

Option 1: You can do this with class like below

#include <iostream>
#include <complex>
#include <cmath>

using namespace std;

const complex<double> Im1 (0.0, 1.0); //imaginary number definition

class Functions {
public:
    complex<double> dN (complex<double> **N, int k, int i, complex<double> kN, double T1) 

    {
        complex<double> OUT = Im1*(N[k][i] + kN) / (T1);

        return OUT;
    };

};

int main (int argc, const char * argv[]) {

    //...more code here

    complex<double> **NM = new complex<double>*[1000]; //1000x500 array
                                                 //run loop to initialize
    for (int i = 0; i < 1000; ++i)
    {
        NM[i] = new complex<double>[500];
    }

    Functions fun; //create class instance 

     //call the function NOTE the changes here i.e not correct passing **NM
    complex<double> dN_OUT = fun.dN (NM, 1, 20, 0., 20.);

    return 0;
};

Option 2 (mentioned by others direct calling with changes instead of **NM you should use NM.

complex<double> dN(complex<double> **N, int k, int i, complex<double> kN, double T1){
    ...
}

int main(int argc, const char * argv[]) {
    ...
    complex<double> dN_OUT = dN(NM,1,20,0.,20.);
}
Pang
  • 9,564
  • 146
  • 81
  • 122
RaspiRepo
  • 78
  • 2