繁体   English   中英

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

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

我正在尝试使用模板在 C++ 中编译示例程序。 模板 class 有一个 priavte static 成员变量,在尝试编译时似乎未定义。 通过 SO 上的其他答案,我意识到这个变量也需要定义。 然而,到目前为止,我尝试定义这个变量都没有成功,这可能是因为我缺乏使用模板的经验。 这是我的示例程序:

#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;
}

这产生:

$ 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

我尝试将pv_mem_定义为:

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

但这导致了以下错误:

$ 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_;
                                                                            ^

初始化此变量的正确方法是什么?

pv_mem_定义如下

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

它使用&来获取FruitFunction<TotalFruits>的地址,但是由于FruitFunction只是声明而没有定义,它会在运行时产生一个未定义的引用错误。

添加模板 function FruitFunction的定义将解决 C++17 中的问题

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

C++11中constexpr static成员变量还需要定义在class之外,所以还需要加上

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

演示

暂无
暂无

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

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