在 C++ 中初始化模板 class 私有静态变量
Initialize a template class private static variable in C++
我正在尝试使用模板在 C++ 中编译示例程序。模板 class 有一个私有静态成员变量,在尝试编译时似乎未定义。通过 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
只是声明的,没有定义,所以会生成运行时出现未定义的引用错误。
添加模板函数的定义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_;
我正在尝试使用模板在 C++ 中编译示例程序。模板 class 有一个私有静态成员变量,在尝试编译时似乎未定义。通过 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
只是声明的,没有定义,所以会生成运行时出现未定义的引用错误。
添加模板函数的定义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_;