Thread: vector of function pointers

  1. #16
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    That's clearly different [...] staring me in the face?
    O_o

    I think the suggestion was offered because it can simplify the implementation of additional features. That doesn't change the registration requirement or imply that your now doing something illegal. You see, by storing a generated function object you can easily support simple functions but you can also, for example, bind an object to a member function so that you might perform the same mechanical test on different prefabricated data without complicating the implementation of the tests themselves.

    Soma

  2. #17
    3735928559
    Join Date
    Mar 2008
    Location
    RTP
    Posts
    838
    i offered it up because i thought it was relevant to your attempts to store the pointer-to-member functions in a vector.

    if you succeed in navigating the syntax of calling a pointer-to-member function from an STL container, you will get an error saying: "illegal use of member pointer" (IIRC) . though perhaps this is specific to set, as in the cited thread, and does not apply to vectors.

    using a function object both skirts this limitation and simplifies the syntax; not to mention simplifying your life by being able to process the i/o of the function on each call with no additional effort. using a derived template allows you to store functions that varying types and numbers of arguments in the same container and invoke them through the base class' virtual invocation method (exec)
    Last edited by m37h0d; 12-11-2008 at 03:40 PM.

  3. #18
    Registered User
    Join Date
    Feb 2003
    Posts
    596
    Thanks, I appreciate that m37h0d's approach is much more versatile. But right now I'm trying to understand this particular error. Maybe it is even clearer if I modify the main function code, effectively taking the STL container out of the picture
    Code:
    // fn_pointer3.cpp
    
    #include <iostream>
    #include <vector>
    #include "funcs3.h"
    #include <cassert>
    using namespace std;
    
    
    int main () {
    //  vector<int (*)(int,int)> funcs;
      vector<int (functions::*)(int,int)> funcs;
      functions f(funcs);
      assert(!funcs.empty());
      int x,y,op,sum;
      cout << "1. add\n2. multiply\n\tChoose 1 or 2\n";
      cin >> op;
      cout << "enter 2 operands:\n";
      cin >> x >> y;
      int (functions::*fptr)(int,int);
      fptr = *funcs.begin();
      sum = fptr(x,y);
      cout << "the result is " << sum << "\n";
    }
    Now the error is simply
    Code:
    In function `int main()':
    fn_pointer3.cpp:22: error: must use .* or ->* to call pointer-to-member
       function in `fptr (...)'
    So, is it illegal to use a member function pointer from outside of the class, even if the member function is public?

  4. #19
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    You can't use a member function without an object.
    You can't use a pointer to a member function without an object.

    You need to read that thread he linked a few more times.

    Soma

  5. #20
    Registered User
    Join Date
    Feb 2003
    Posts
    596
    Quote Originally Posted by phantomotap View Post
    You need to read that thread he linked a few more times.

    Soma
    I've read it. The problem is different. My vector is not the source of the problem The problem is how to use the member function pointers.
    I accept your statement that "You can't use a member function without an object. You can't use a pointer to a member function without an object."
    But if I modify the next-to-last line of my code just above (post # ) to
    Code:
    sum = f.fptr(x,y)
    similar to the way you might use an ordinary (non-member) function pointer, I get an error
    Code:
    error: 'fptr' undeclared (first use this function)
    which I suppose makes sense because f does not have a member called 'fptr'. But if I change it to
    Code:
    sum = f.(*fptr)(x,y)
    I get an error
    Code:
    error: syntax error before '*' token
    error: invalid use of 'unary *' on pointer to member
    There is no error associated with the line "fptr = *funcs.begin();

    and this is interesting... If I modify the code as follows, it compiles and runs, but fails at the FIRST assert - although the types are consistent, the functions constructor doesn't put anything into the vector.
    Code:
    // fn_pointer3.cpp MODIFIED
    
    #include <iostream>
    #include <vector>
    #include "funcs3.h"
    #include <cassert>
    using namespace std;
    
    
    int main () {
    //  vector<int (*)(int,int)> funcs;
      vector<int (functions::*)(int,int)> funcs;
      functions f(funcs);
      assert(!funcs.empty());
      int x,y,op,sum;
      cout << "1. add\n2. multiply\n\tChoose 1 or 2\n";
      cin >> op;
      cout << "enter 2 operands:\n";
      cin >> x >> y;
      int (functions::*fptr)(int,int);
      fptr = *funcs.begin();
      assert (fptr == &functions::add);
    //  sum = f.(*fptr)(x,y);
    //  cout << "the result is " << sum << "\n";
    }
    (using the same funcs3.h and funcs3.cpp as in post #11)

    Anyway, this seems to be going nowhere. Function objects are not the same thing as pointers to member functions. Don't the unit test libraries that laserlight mentioned use pointers to member functions? Or not? I wouldn't expect that all classes that are tested by those tools must have each function in its own class.
    Last edited by R.Stiltskin; 12-11-2008 at 05:05 PM. Reason: added reference to post #11 after the last code block

  6. #21
    Registered User
    Join Date
    Feb 2003
    Posts
    596
    In fact it has nothing to do with STL containers at all. I just added a functions class constructor that takes a single int (functions::*)(int,int) and supposedly assigns &functions::add to it. Main declares an
    int (functions::*fptr)(int,int)=NULL;
    and calls the new constructor passing it fptr. It compiles and runs, but halts on assert(fptr).

  7. #22
    3735928559
    Join Date
    Mar 2008
    Location
    RTP
    Posts
    838
    no, your problem is not different. soma is telling you the information you need, he's just not elaborating very much.

    to call an pointer-to-member function, you have to have two pieces of information: an instance of the class that will invoke the method, and the method you want called.

    you aren't storing an instance of the object.

    if you insist on banging on in this way, perhaps you could use a vector of pairs (or a map), and store the class instance in pair::first and the function in pair::second, then do something like

    containerType::iterator it = container.begin();
    (it->first.*it->second)(arg)

    this might not work, but it should have everything required to call the pointer-to-member function. it was meant to demonstrate that you are missing information required to call the member function.
    Last edited by m37h0d; 12-11-2008 at 05:26 PM.

  8. #23
    3735928559
    Join Date
    Mar 2008
    Location
    RTP
    Posts
    838
    that does, in fact, work.

    Code:
    //---------------------------------------------------------------------------
    #include <map>
    #include <vcl.h>
    #pragma hdrstop
    
    //---------------------------------------------------------------------------
    
    #pragma argsused
    class c
    {
    
            public:
    
            int func(int i0,int i1)
            {
                    return i0+i1;
            }
    };
    int main(int argc, char* argv[])
    {
            typedef int (c::*iiifuncptr)(int,int);
            typedef std::map<c*,iiifuncptr>cFuncMap;
            cFuncMap fm;
            c c1;
            fm[&c1]=&c::func;
            cFuncMap::iterator it = fm.begin();
            int i = (*it->first.*it->second)(1,2);
            return 0;
    }
    //---------------------------------------------------------------------------

  9. #24
    Registered User
    Join Date
    Feb 2003
    Posts
    596
    In your example, the code that stores the member function pointer is outside the class. I'm trying to do something from within the class - in the constructor.
    This code compiles & runs but leaves the function pointer fptr NULL. Why?
    Code:
    #include <iostream>
    #include <cassert>
    
    class c {
      public:
      c(int (c::*fptr)(int,int)) {
          fptr = &c::add;
          std::cout << "finished c constructor\n";
      }
      int add(int x,int y) {return x+y;}
      int mult(int x,int y) {return x*y;}
    };
    
    
    int main () {
      int (c::*fptr)(int,int) = NULL;
      c f(fptr);
      std::cout << fptr << "\n";
      assert(fptr);
    }
    Last edited by R.Stiltskin; 12-11-2008 at 07:48 PM. Reason: removed extra c:: from the constructor

  10. #25
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    You don't expect to be able to change the value of a non-reference variable inside a function, do you?

  11. #26
    Registered User
    Join Date
    Feb 2003
    Posts
    596
    That would seem to be a bad thing. On the other hand, the compiler doesn't seem to mind.

    I tried to make the pointer const, but couldn't figure out any syntax to accomplish that.

  12. #27
    3735928559
    Join Date
    Mar 2008
    Location
    RTP
    Posts
    838
    Code:
    //---------------------------------------------------------------------------
    #include <iostream>
    #include <cassert>
    
    #include <vcl.h>
    #pragma hdrstop
    
    //---------------------------------------------------------------------------
    
    #pragma argsused
    
    class c {
      public:
      c(int (c::**fptr)(int,int)) {
          *fptr = &c::add;
          std::cout << "finished c constructor\n";
      }
      int add(int x,int y) {return x+y;}
      int mult(int x,int y) {return x*y;}
    };
    
    
    
    int main(int argc, char* argv[])
    {
      int (c::*fptr)(int,int) = NULL;
      c f(&fptr);
      std::cout << fptr << "\n";
      assert(fptr);
    }
    //---------------------------------------------------------------------------
    Last edited by m37h0d; 12-11-2008 at 08:03 PM.

  13. #28
    Registered User
    Join Date
    Feb 2003
    Posts
    596
    This is probably a waste of time. Your code puts something in fptr, but I still can't work out how to use it.
    This, for example, won't compile
    Code:
    #include <iostream>
    #include <cassert>
    
    //#include <vcl.h>
    //#pragma hdrstop
    
    //---------------------------------------------------------------------------
    
    //#pragma argsused
    
    class c {
      public:
      c(int (c::**fptr)(int,int)) {
          *fptr = &c::add;
          std::cout << "finished c constructor\n";
      }
      int add(int x,int y) {return x+y;}
      int mult(int x,int y) {return x*y;}
    };
    
    
    
    int main(int argc, char* argv[])
    {
      int (c::*fptr)(int,int) = NULL;
      c f(&fptr);
      std::cout << fptr << "\n";
      assert(fptr);
      int result = f.(*fptr)(1,2);
    
    }
    nor will any other combination of f . -> *() that I have tried, following the compiler's suggestions.

  14. #29
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    The error message says that you need to use .* to call a member pointer. I would believe it, if I were you.
    Code:
    int result = (f.*fptr)(1,2);

  15. #30
    Registered User
    Join Date
    Feb 2003
    Posts
    596
    Apparently I didn't try ALL permutations.

    Thanks. I will need some time to think about what I have learned from this discussion.

    What about your question a few posts back? Does this pointer now allow messing around with the member function itself - violating the encapsulation?

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Class function pointers
    By VirtualAce in forum C++ Programming
    Replies: 40
    Last Post: 02-17-2005, 12:55 AM
  2. pointers
    By InvariantLoop in forum C Programming
    Replies: 13
    Last Post: 02-04-2005, 09:32 AM
  3. Request for comments
    By Prelude in forum A Brief History of Cprogramming.com
    Replies: 15
    Last Post: 01-02-2004, 10:33 AM
  4. Contest Results - May 27, 2002
    By ygfperson in forum A Brief History of Cprogramming.com
    Replies: 18
    Last Post: 06-18-2002, 01:27 PM
  5. function pointers and member functions
    By thor in forum C++ Programming
    Replies: 5
    Last Post: 03-19-2002, 04:22 PM