简体   繁体   English

在C++初始化一个模板class私有static变量

[英]Initialize a template class private static variable in C++

I'm trying to compile a sample program in C++ using templates.我正在尝试使用模板在 C++ 中编译示例程序。 The template class has a priavte static member variable which seems to be undefined when trying to compile.模板 class 有一个 priavte static 成员变量,在尝试编译时似乎未定义。 Going through other answers on SO, I realized that this variable needs to be defined as well.通过 SO 上的其他答案,我意识到这个变量也需要定义。 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:我尝试将pv_mem_定义为:

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?初始化此变量的正确方法是什么?

pv_mem_ is defined as follows pv_mem_定义如下

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

which uses & to take the address of FruitFunction<TotalFruits> , but since FruitFunction is only declared and not defined, it will generate an undefined reference error at runtime.它使用&来获取FruitFunction<TotalFruits>的地址,但是由于FruitFunction只是声明而没有定义,它会在运行时产生一个未定义的引用错误。

Adding the definition for the template function FruitFunction will solve the problem in C++17添加模板 function FruitFunction的定义将解决 C++17 中的问题

template <FRUIT T>
void FruitFunction() { /* */ }

In C++11, constexpr static member variables still need to be defined outside the class, so you also need to add C++11中constexpr static成员变量还需要定义在class之外,所以还需要加上

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

Demo演示

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM