如何在 C++ 中为模板实现静态变量功能
How to implement static variable functionality for templates in C++
我正在处理设计难题,非常感谢您的想法。
我已经实现了一个模板 class PacketManager,它为作为模板给出的不同类型的数据包实现了资源管理器的功能。对于每种类型的数据包,我只有一个实例(单例),我想有一个计数器来计算为不同类型的数据包生成的 PacketManager 实例的数量(因此基本上计算系统中数据包类型的数量)。
自然地,人们会使用一个 static int 变量并在每次实例化时递增它。但是对于模板,我不能只为所有模板实例使用一个静态变量。相反,我对每种数据包类型都有一个静态变量。
你们能想出一个干净的解决方案,让我可以获得我需要的功能吗?
我想到的唯一解决方案是定义一个不理想的全局变量。
您可以将其范围限定在另一个函数内,而不是全局变量:
size_t get_or_increment_counter(bool inc) {
static size_t counter = 0;
if (inc) counter++;
return counter;
}
您的模板函数将调用:
template <typename T>
class PacketManager {
private:
std::shared_ptr<T> construct() {
get_or_increment_counter(true);
return std::make_shared(...);
}
public:
T& get_instance() {
static std::shared_ptr<T> ptr = construct();
return *ptr;
}
};
这是一个错误的前提:
However for templates I can't have just one static variables for all template instances.
是的,你可以:
#include <iostream>
struct Base {
static int counter;
Base() { counter++; }
};
int Base::counter = 0;
template <typename T>
struct Foo : Base {};
int main(int argc, char** argv) {
Foo<int> x;
Foo<double> y;
Foo<float> z;
std::cout << Base::counter;
}
3
实际上,这并不是您当前遇到的问题所特有的。一般来说,任何不依赖于模板参数的东西都可以移动到非模板基础 class.
我正在处理设计难题,非常感谢您的想法。 我已经实现了一个模板 class PacketManager,它为作为模板给出的不同类型的数据包实现了资源管理器的功能。对于每种类型的数据包,我只有一个实例(单例),我想有一个计数器来计算为不同类型的数据包生成的 PacketManager 实例的数量(因此基本上计算系统中数据包类型的数量)。 自然地,人们会使用一个 static int 变量并在每次实例化时递增它。但是对于模板,我不能只为所有模板实例使用一个静态变量。相反,我对每种数据包类型都有一个静态变量。 你们能想出一个干净的解决方案,让我可以获得我需要的功能吗? 我想到的唯一解决方案是定义一个不理想的全局变量。
您可以将其范围限定在另一个函数内,而不是全局变量:
size_t get_or_increment_counter(bool inc) {
static size_t counter = 0;
if (inc) counter++;
return counter;
}
您的模板函数将调用:
template <typename T>
class PacketManager {
private:
std::shared_ptr<T> construct() {
get_or_increment_counter(true);
return std::make_shared(...);
}
public:
T& get_instance() {
static std::shared_ptr<T> ptr = construct();
return *ptr;
}
};
这是一个错误的前提:
However for templates I can't have just one static variables for all template instances.
是的,你可以:
#include <iostream>
struct Base {
static int counter;
Base() { counter++; }
};
int Base::counter = 0;
template <typename T>
struct Foo : Base {};
int main(int argc, char** argv) {
Foo<int> x;
Foo<double> y;
Foo<float> z;
std::cout << Base::counter;
}
3
实际上,这并不是您当前遇到的问题所特有的。一般来说,任何不依赖于模板参数的东西都可以移动到非模板基础 class.