1

use C++98. I have a struct t_fd which is used inside a class MS. In the struct there are two pointers to function: fct_read, fct_write. I designed that the function pointers are pointing to the two methods of the class. But then I have this error when trying to call them.

expression preceding parentheses of apparent call must have (pointer-to-) function type.

Please advice on the error, also on the design. I need the two functions are methods of that class because I need to use class's attributes (even though it isn't showed here for the shake of simplicity). Thank you for your time, I appreciate your help!

#include <vector>
#include <iostream>

typedef struct  s_fd {
    void(MS::*fct_read) (int);
    void(MS::*fct_write) (int);
}   t_fd;

class MS
{
    private:
        std::vector< t_fd >            _fdSet;

        void        server_accept(int s)
        {
            if (s % 2 == 0)
                _fdSet[cs].fct_read = MS::client_read;
            else
                _fdSet[cs].fct_write = MS::client_write;
        }

        void        client_read(int fd)
        {
            std::cout << "I'm reading\n";
        }

        void        client_write(int fd)
        {
            std::cout << "I'm writing\n";
        }

        void        check_fd()
        {
            int i = 0;
            int size = 10;

            while (i < size)
            {
                if (i < 5)
                    _fdSet[i].fct_read(i); //Error here!
                if (i >= 5)
                    _fdSet[i].fct_write(i); //Error here!
                i++;
            }
        }
};

Snow_Ball
  • 47
  • 8
  • 1
    Re: "I use C++98" -- why? – Pete Becker May 16 '22 at 20:27
  • 2
    related/dupe: https://stackoverflow.com/questions/66800751/calling-a-pointer-to-member-function-from-a-struct-array – NathanOliver May 16 '22 at 20:27
  • 2
    At the beginning of `server_accept`, `int cs;` leaves `cs` with an indeterminate value. The code that follows that line use that value, so the code won't do anything meaningful. – Pete Becker May 16 '22 at 20:30
  • Since everything inside `MS` is private there's nothing any other code can do with it. – Pete Becker May 16 '22 at 20:32
  • 3
    The syntax for calling with a pointer-to-member-function uses `.*` or `->*`; the calls as written simply can't work. Off the top of my head, `(this->*_fdSet[I].fct_read)(i);` is the way to do it. – Pete Becker May 16 '22 at 20:35
  • 1
    `std::vector _fdSet;` creates a vector with no elements. Assigning anything to `_fsSet[cs]` results in undefined behavior, because there is no such element. When you add to an empty vector use `push_back`. – Pete Becker May 16 '22 at 20:37
  • 1
    @PeteBecker: Thank you for your comments. It works now. I also read the link, it's really helpful. - For the cs, you're right. I edited the code to be meaningful. - For the vector _fdSet, I did add elements to it by using push_back but it does not show here. - I need everything is in private and it seems to have no problem. But I keep an eye on it if ever I encounter problem in the future. - C++98 because I have to (school project). – Snow_Ball May 16 '22 at 20:46
  • @PeteBecker: I now have this error: `cannot convert ‘MS::client_read’ from type ‘void (MS::)(int)’ to type ‘void (MS::*)(int)’` in the function `server_accept`. Do you know why? – Snow_Ball May 16 '22 at 21:09
  • 2
    The correct syntax for creating a pointer-to-member-function is `&MS::client_read`. Do you have a good book to learn from? – Pete Becker May 16 '22 at 21:18

1 Answers1

4

The intent of your code is difficult to understand (in its current form). But I would be happy to solve few issues in your code.

  1. MS class needs to be declared before you reference it the type from s_fd structure definition :
class MS; // forward declaration
    
typedef struct  s_fd {
void(MS::* fct_read) (int);
void(MS::* fct_write) (int);
}   t_fd;
    
class MS
{  ... }
  1. the syntax to assign function pointer is incorrect. You forgot &:
_fdSet[cs].fct_read = &MS::client_read;
  1. fct_read and fct_write are member function pointers. They should be applied on instance of MS class. In case you want to apply them on this object:
if (i < 5) {
  auto fptr = _fdSet[i].fct_read;
  (this->*fptr)(i);
}
Ivan_a_bit_Ukrainivan
  • 808
  • 1
  • 10
  • 27