dimanche 17 avril 2022

Initialize a template class private static variable in C++

I'm trying to compile a sample program in C++ using templates. The template class has a priavte static member variable which seems to be undefined when trying to compile. Going through other answers on SO, I realized that this variable needs to be defined as well. However my attempts at defining this variable have been unsuccessful so far, likely due to my lack of experience working with templates. Here is my sample program:

#include <iostream>
#include <array>

enum FRUIT
{
    APPLE,
    ORANGE
};

using FunctionPtr = void(*)(void);

template <FRUIT T>
void FruitFunction(void);

template <FRUIT...TotalFruits>
class TestClass
{
public:

    struct fruitGroup
    {
        FRUIT fruit;
        FunctionPtr func;
    };

    static int find_fruit(FRUIT fruit, int arg)
    {
        for (auto i = pv_mem_.begin(); i != pv_mem_.end(); ++i) {
            if (i->fruit == fruit) {
                break;
            }
        }

        return 0;
    }

private:
    constexpr static std::array<fruitGroup, sizeof...(TotalFruits)> pv_mem_ 
    {
        fruitGroup{TotalFruits, &FruitFunction<TotalFruits>}...
    };
};

int main()
{
    TestClass<FRUIT::APPLE, FRUIT::ORANGE> test;
    test.find_fruit(FRUIT::APPLE, 0);

    return 0;
}

This yields:

$ g++ -std=c++11 fruit.cpp -o foo
/tmp/ccqaSBYm.o: In function `TestClass<(FRUIT)0, (FRUIT)1>::find_fruit(FRUIT, int)':
fruit.cpp:(.text._ZN9TestClassIJL5FRUIT0ELS0_1EEE10find_fruitES0_i[_ZN9TestClassIJL5FRUIT0ELS0_1EEE10find_fruitES0_i]+0xf): undefined reference to `TestClass<(FRUIT)0, (FRUIT)1>::pv_mem_'
fruit.cpp:(.text._ZN9TestClassIJL5FRUIT0ELS0_1EEE10find_fruitES0_i[_ZN9TestClassIJL5FRUIT0ELS0_1EEE10find_fruitES0_i]+0x1d): undefined reference to `TestClass<(FRUIT)0, (FRUIT)1>::pv_mem_'
collect2: error: ld returned 1 exit status

I have tried defining pv_mem_ as:

constexpr static std::array<TestClass::fruitGroup, sizeof...(TotalFruits)> pv_mem_;

but that resulted in the following error:

$ g++ -std=c++11 fruit.cpp -o foo
fruit.cpp:44:74: error: wrong number of template arguments (1, should be 2)
 constexpr static std::array<TestClass::fruitGroup, sizeof...(TotalFruits)> pv_mem_;
                                                                          ^
In file included from fruit.cpp:2:0:
/usr/include/c++/5/array:89:12: note: provided for ‘template<class _Tp, long unsigned int _Nm> struct std::array’
     struct array
            ^
fruit.cpp:44:76: error: uninitialized const ‘pv_mem_’ [-fpermissive]
 constexpr static std::array<TestClass::fruitGroup, sizeof...(TotalFruits)> pv_mem_;
                                                                            ^

What would be the right way to initialize this variable?

Aucun commentaire:

Enregistrer un commentaire