Home > OS >  An alias for a function pointer declared by "using"
An alias for a function pointer declared by "using"

Time:11-06

I have declared an alias for a function pointer with "using" keyword, but I don't know how to use the alias.

In UpdateState function of Person class, I want to substitude m_state for the return value of the function corresponding to the current state and the one you want to transition to next. However, the error below occurs on the line 38 in Person.cpp and I don't know how to correct the line. I think I am using the alias array wrong.

error C2064: term does not evaluate to a function taking 1 arguments

Person.h

#pragma once

enum STATE
{
    A,
    B,
    C,
    D,
    E,
    STATE_NUM,
};

class Person
{
public:
    Person();
    ~Person();
    void UpdateState();
    STATE IsInStateA(char nextState);
    STATE IsInStateB(char nextState);
    STATE IsInStateC(char nextState);
    STATE IsInStateD(char nextState);
    STATE IsInStateE(char nextState);
private:
    STATE m_state;
};

Person.cpp

#include <iostream>
#include "Person.h"

Person::Person()
    :m_state(A)
{
}

Person::~Person()
{
}

void Person::UpdateState()
{
    char inputArray[] = { 'a','b','c','d','e' };
    char nextStateInput;
    while (1) {
        std::cout << "Please input the state you want to transition to next: ";
        std::cin >> nextStateInput;
        for (int i = 0; i < sizeof inputArray / sizeof inputArray[0];   i) {
            if (nextStateInput == inputArray[i]) {
                break;
            }
        }
        std::cout << "Please enter one of the letters a-e." << std::endl;
    }
    using StateFunc = STATE(Person::*)(char);
    StateFunc stateFuncTable[STATE_NUM] = {
        IsInStateA,
        IsInStateB,
        IsInStateC,
        IsInStateD,
        IsInStateE
    };

    for (int i = 0; i < STATE_NUM;   i) {
        if (nextStateInput == inputArray[i]) {
            m_state = stateFuncTable[m_state](nextStateInput);  //The error occurs on this line.
        }
    }
}

STATE Person::IsInStateA(char nextState)
{
    switch (nextState) {
    case 'b':
        return B;
    case 'd':
        return D;
    default:
        return A;
    }
}

STATE Person::IsInStateB(char nextState)
{
    switch (nextState) {
    case 'c':
        return C;
    case 'd':
        return D;
    case 'e':
        return E;
    default:
        return B;
    }
}

STATE Person::IsInStateC(char nextState)
{
    switch (nextState) {
    case 'b':
        return B;
    default:
        return C;
    }
}

STATE Person::IsInStateD(char nextState)
{
    switch (nextState) {
    case 'a':
        return A;
    case 'e':
        return E;
    default:
        return D;
    }
}

STATE Person::IsInStateE(char nextState)
{
    switch (nextState) {
    case 'a':
        return A;
    case 'b':
        return B;
    default:
        return E;
    }
}

CodePudding user response:

To get a pointer to a non-static member the syntax is &ClassName::membername.

Additionally, a call using the pointer to member function is made using either .* or ->*.

Below is the modified working example where I've added comments to show the changes i've made:

void Person::UpdateState()
{
    char inputArray[] = { 'a','b','c','d','e' };
    char nextStateInput;
    while (1) {
        std::cout << "Please input the state you want to transition to next: ";
        std::cin >> nextStateInput;
        for (int i = 0; i < sizeof inputArray / sizeof inputArray[0];   i) {
            if (nextStateInput == inputArray[i]) {
                break;
            }
        }
        std::cout << "Please enter one of the letters a-e." << std::endl;
    }
    using StateFunc = STATE(Person::*)(char);
    StateFunc stateFuncTable[STATE_NUM] = {
        &Person::IsInStateA,       //added &Person:: here
        &Person::IsInStateB,       //added &Person:: here 
        &Person::IsInStateC,       //added &Person:: here
        &Person::IsInStateD,       //added &Person:: here
        &Person::IsInStateE        //added &Person:: here
    };;

    for (int i = 0; i < STATE_NUM;   i) {
        if (nextStateInput == inputArray[i]) {
//---------------------vvvvvvv---------------------->correct syntax using ->*
            m_state = (this->*stateFuncTable[m_state])(nextStateInput);  
        }
    }
}

Working demo


With C 17 you can use std::invoke instead of ->* as shown below:

m_state = std::invoke(stateFuncTable[m_state], this, nextStateInput);

Demo C 17

  • Related