0

If I enable line number 4 in below code then I end up in getting compilation error , while I am doing same thing (calling getFp1) outside the class and that works perfectly fine .

**Compilation Error** : In member function 'std::function<void(std::__cxx11::basic_string<char>)> testClass::getFp()':
Practice.cpp:23:14: error: cannot convert 'testClass::myTestFunction' from type 'void (testClass::)(std::string)' {aka 'void (testClass::)(std::__cxx11::basic_string<char>)'} to type 'std::function<void(std::__cxx11::basic_string<char>)>'
   23 |       return myTestFunction;
      |              ^~~~~~~~~~~~~~

Code

#include <iostream>
#include <functional>
#include <string>
//#define CLASS 1     -------------> Enabling this throws compilation error (?)
using namespace std;

void printMessage(string str){
    cout << str << endl;
}

void testFunction(std::function<void(std::string)> fp,string s){
   fp(s);
}
#ifdef CLASS
class testClass {

public :   
   void myTestFunction(std::string s){
      cout << s << endl;
   }
public : 
   std::function<void(std::string) > getFp(){
      return myTestFunction;
   }
};
#endif 

std::function<void(std::string) > getFp1(){
      return printMessage;
}

int main(){
   std::function<void(string)> fp = printMessage;
   fp("Whats up !!") ;
   testFunction(fp,"All is Well");
#ifdef CLASS
   testClass t ; 
   auto fp1 = t.getFp();
   fp1("Calling Private Method ?");
#endif

   auto fp2 = getFp1();
   fp2("Great !!");
   return 0;
}

============================

Jason
  • 36,170
  • 5
  • 26
  • 60
Milind
  • 3
  • 1
  • I am aware that above could be rectified by using std::bind or Lambda , but was keen on this particular error which kept me busy yesterday .. – Milind Aug 07 '22 at 05:40
  • Do you know what `#ifdef` do? It is straightforward. Also see this: [Why can std::function bind functions of different types?](https://stackoverflow.com/questions/72598253/why-can-stdfunction-bind-functions-of-different-types/72601919#72601919) – Jason Aug 07 '22 at 05:43
  • Tip: before assuming that "returning" is a relevant factor, try assigning to a variable. In this case, that would mean something like `std::function getFp(){ std::function retval = myTestFunction; return retval; }`.When the assignment fails, you can deduce that the restriction is not specific to returning a value. – JaMiT Aug 07 '22 at 17:25
  • Tip: When doing a comparison, try to limit the number of things that change. To really be "doing same thing" in `getFp` and `getFp1`, they should attempt to return the same thing. That is, change `getFp` so that its body is `return printMessage;`. (Changing `getFp1` would also be an option, if you know how to refer to `myTestFunction` outside the class.) When `getFp` successfully returns `printMessage`, you can conclude that the problem stems from what you are returning, not where the return happens. – JaMiT Aug 07 '22 at 17:33

1 Answers1

0

This is a variation on the member functions are not regular functions question we get so often. Your code can be made to work like this

public : 
    std::function<void(testClass&,std::string) > getFp(){
        return &testClass::myTestFunction;
    }
};

and to call this method

testClass t ; 
auto fp1 = t.getFp();
fp1(t, "Calling Private Method ?");

Not sure if this is acceptable to you or not.

john
  • 85,011
  • 4
  • 57
  • 81