模板化的配置值类和全局列表

templated config value class and global list

本文关键字:全局 列表 配置      更新时间:2023-10-16

嘿,我正试图实现一个简单的配置值类,其中包含这些值的全局列表。我的实现是这样的:

template <typename Y>
class ConfigSetting;
template <typename T>
class Global {
public:
     static ConfigSetting<T>* head;
     static ConfigSetting<T>* tail;
};
template <typename T>
class ConfigSetting {
public:
    ConfigSetting(const std::string& name, const std::string& synopsis, T initValue) : m_name(name), m_synopsis(synopsis), m_value(initValue)
    {
        this->addToList();
    }
    static ConfigSetting* findSetting(const std::string& name)
    {
        if (Global<T>::head) {
            Global<T> temp = Global<T>::head;
            while (!temp) {
                if (temp->m_name == name) {
                    return Global<T>::head;
                }
                temp = temp->m_next;
            }
        }
        return nullptr;
    }
private:
    void addToList(void)
    {
        if (Global<T>::head) {
            Global<T>::tail->m_next = this;
            Global<T>::tail = this;
        }
        else {
            Global<T>::head = this;
            Global<T>::tail = this; 
        }
    }
    ConfigSetting* m_next;
    const std::string m_name;
    const std::string m_synopsis;
T m_value;
T m_min;
T m_max;

现在编译得很好,但是给了我两个链接错误:

error LNK2001: unresolved external symbol "public: static class ConfigSetting<int> * Global<int>::head" (?head@?$Global@H@@2PAV?$ConfigSetting@H@@A)
error LNK2001: unresolved external symbol "public: static class ConfigSetting<int> * Global<int>::tail" (?tail@?$Global@H@@2PAV?$ConfigSetting@H@@A)

我相信这与我在顶部创建的那种循环依赖关系有关。我该如何解决这个问题,或者是否有更好的方法来使用模板?我不想为我想支持的每种类型创建一个类。

链接器错误总是相同的错误:您的链接器没有代码。一旦你明白了这一点,你就可以很容易地解决链接错误:)在本例中,缺少的代码是静态变量的定义。在你的类中,你声明它们,但是你没有定义它们。下面是定义类模板的静态变量的语法:使用静态变量和模板

我认为你在这里把模板类弄乱了(它们是c++中很难的一部分,所以不要对此感到不满:)

我想这就是你想要做的:

#include "stdafx.h"
#include <string>
using namespace std;
template <typename T>
class ConfigSetting {
public:
    static ConfigSetting* head; // I fixed here, no need for Global, you have this class static vars
    static ConfigSetting* tail;
public:
    ConfigSetting(const std::string& name, const std::string& synopsis, T initValue) : m_name(name), m_synopsis(synopsis), m_value(initValue)
    {
        this->addToList();
    }
    static ConfigSetting* findSetting(const std::string& name)
    {
        if (head) {
            ConfigSetting* temp = head;
            while (!temp) {
                if (temp->m_name == name) {
                    return temp; // I fixed here, you have to return the object you find
                }
                temp = temp->m_next;
            }
        }
        return nullptr;
    }
private:
    void addToList() // no need for 'void' this is C++, not C
    {
        if (head) {
            tail->m_next = this;
            tail = this;
        }
        else {
            head = this;
            tail = this; 
        }
    }
    ConfigSetting* m_next;
    const std::string m_name;
    const std::string m_synopsis;
    T m_value;
    T m_min;
    T m_max;
};
template <typename T>
ConfigSetting<T>* ConfigSetting<T>::head = nullptr;
template <typename T>
ConfigSetting<T>* ConfigSetting<T>::tail = nullptr;
int _tmain(int argc, _TCHAR* argv[])
{
    ConfigSetting<int> j("name", "syn", 1);
    return 0;
}

在类外定义静态的headtail指针

   template<typename T>
    ConfigSetting<T>*  Global<T>::tail = nullptr ;
   template<typename T>
    ConfigSetting<T>*  Global<T>::head = nullptr ;