-3

I have a class that hold public static method corresponding to mathematical operations. The class is implemented like such

class test
{
    public:
        test(){};
        ~test(){};
        typedef int(test::*calcul)(int a,int b);
        /*STATIC METHOD*/
        static int add(int a, int b);
        static int divide(int a, int b);
        static int multiply(int a, int b);
        static int substract(int a, int b);
        static calcul _calcul[128];
    private:
        /* data */
};

I also added an array of pointer to function so that I can store these functions into that array and use them for later. However I have an error when I try to initialize the static array in the implementation file. Here is the error I get:

test.cpp:34:14: error: conflicting declaration ‘int (test::* test::_calcul [43])(int, int)’
   34 | test::calcul test::_calcul['+'] = test::add;
      |              ^~~~
test.cpp:15:23: note: previous declaration as ‘int (test::* test::_calcul [128])(int, int)’
   15 |         static calcul _calcul[128];

To initialize one of the indexex of the array here what I wrote:

test::calcul test::_calcul['+'] = test::add;

My assumption of the above code sample is that the _calcul array at index '+' will be initialized with the function pointer of the add static method however it is not what is actually happening.

Here is the full program:

#include <cstdlib>
#include <iostream>

class test
{
    public:
        test(){};
        ~test(){};
        typedef int(*calcul)(int a,int b);
        /*STATIC METHOD*/
        static int add(int a, int b);
        static int divide(int a, int b);
        static int multiply(int a, int b);
        static int substract(int a, int b);
        static calcul _calcul[128];
    private:
        /* data */
};

/*----------------------------------STATIC MEMBER FUNCTION----------------------------------*/
int test::add(int a, int b){return a + b;};
int test::substract(int a, int b){return a - b;};
int test::multiply(int a, int b){return a * b;};
int test::divide(int a, int b)
{
    if (b == 0)
    {
        std::cerr << "Error\n";
        exit(1);
    }
    return a / b;
};
/*----------------------------------STATIC MEMBER FUNCTION----------------------------------*/
test::calcul test::_calcul['+'] = test::add;

int main(void)
{
    test d;
}
toure
  • 1
  • 3
  • 4
    Because *class static* functions are **not** *member functions*. The `typedef calcul` is for *member functions*. Did you intend `typedef int(*calcul)(int a,int b);`? – Eljay Mar 17 '23 at 14:15
  • 3
    Can you [edit] this post so the code shown produces the error shown? – Drew Dormann Mar 17 '23 at 14:15
  • 1
    As a side note, you might consider using a C++ type alias (`using calcul = ...`) instead of a C `typedef` for better readability. – Brian61354270 Mar 17 '23 at 14:17
  • @Eljay I want to create an array of function pointer that will store the following 4 method : add, substract, divide, multiply – toure Mar 17 '23 at 14:21
  • 1
    Put `test::_calcul['+'] = &test::add;` inside the `main` function. You can't have global statements in C++, they need to be in a function. (That's something most scripting languages support, and some compiled languages, but not C++.) – Eljay Mar 17 '23 at 14:22
  • Your class is defined once with `typedef int(test::*calcul)(int a,int b);` and in your second code block as `typedef int(*calcul)(int a,int b);`. Which is the real code you are asking about? – Drew Dormann Mar 17 '23 at 14:25
  • @Eljay I got undefined reference to test::_calcul error when following your advice – toure Mar 17 '23 at 14:40
  • In your class you **declare** `_calcul`. Where have you **defined** `_calcul`? – Eljay Mar 17 '23 at 14:52
  • Fixed the error I forgot to declare the static variable – toure Mar 17 '23 at 14:53
  • Consider using a `std::map` instead of a fixed array. You are wasting a lot of unused array slots. And a `std::map` can be initialized statically, eg: `static std::map _calcul; ... std::map test::_calcul = { {'+', &test::add}, {'-', &test::substract}, {'*', &test::multiply}, {'/', &test::divide} };` – Remy Lebeau Mar 17 '23 at 16:15

1 Answers1

1

What you wrote is a definition of an array, not an assignment to an array member. Like the error says, you can't declare and define the same array with different bounds.

C++ does not support designated initializers for arrays, so your best bet would be to use a std::array<calcul, 128> instead of a raw array and write a helper function or lambda that can be used to initialize the static member:

class test
{
public:
    using calcul = int(*)(int, int);
    //...
    static int add(int a, int b);
    static inline const std::array<calcul, 128> _calcul = []() {
        std::array<test::calcul, 128> ret;
        ret['+'] = &calcul::add;
        //...
        return ret;
    }();
    //...
};

Demo

Here I've used an immediately-invoked lambda instead of a separate helper function, but the latter would work as well.

Miles Budnek
  • 28,216
  • 2
  • 35
  • 52