【问题标题】:How to implement static variable functionality for templates in C++如何在 C++ 中为模板实现静态变量功能
【发布时间】:2021-09-06 02:35:25
【问题描述】:

我正在处理一个设计难题,希望能得到您的想法。 我已经实现了一个模板类 PacketManager,它为作为模板给出的不同类型的数据包实现了资源管理器的功能。对于每种类型的数据包,我只有一个实例(单例),我希望有一个计数器来计算为不同类型的数据包生成的 PacketManager 实例的数量(因此基本上计算系统中数据包类型的数量)。 自然地,人们会使用一个静态 int 变量并在每次实例化时递增它。但是对于模板,我不能只为所有模板实例提供一个静态变量。相反,我对每种数据包类型都有一个静态变量。 你们能想出一个干净的解决方案来获得我需要的功能吗? 我想到的唯一解决方案是定义一个不理想的全局变量。

【问题讨论】:

    标签: c++ templates global-variables static-variables


    【解决方案1】:

    这是一个错误的前提:

    但是对于模板,我不能只为所有模板实例设置一个静态变量。

    是的,你可以:

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

    Output:

    3
    

    实际上,这并不是您当前问题所特有的。一般来说,任何不依赖于模板参数的东西都可以移动到非模板基类中。

    【讨论】:

    • 这太棒了。我根本没有想到这个解决方案。
    • @Amir 这就是我最后提到它的原因。您似乎错过了只有依赖于模板参数的东西才需要成为模板的一部分。将所有其他内容移至非模板基类通常会使事情变得更简单(考虑例如特化类模板,那么您只需要特化模板的成员,而不是基类的成员)
    【解决方案2】:

    除了全局变量,您可以将其作用域到另一个函数中:

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

    【讨论】:

    • 谢谢。该函数应该在全局范围内,而不是同一模板类的成员函数。对吗?
    • 是的,如果是在同一个班级,那么这就是你现在看到的同样的问题。
    猜你喜欢
    • 2016-06-06
    • 2010-12-05
    • 1970-01-01
    • 2019-05-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多