【问题标题】:templated config value class and global list模板化配置值类和全局列表
【发布时间】:2014-03-23 18:40:54
【问题描述】:

嘿,我正在尝试使用包含这些值的全局列表来实现一个简单的配置值类。 我的实现如下所示:

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;

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

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)

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

【问题讨论】:

  • 你知道如何在类中使用static变量吗?
  • findSetting 函数中。当您找到的节点是temp 时,您确定要返回列表的头部吗?另外,为什么要使用您自己的列表而不是standard container?在这种情况下,std::unordered_map 将是完美的。
  • 是的,您对我想要返回的内容是正确的。 @P0W:我知道这被认为是一个提示,但我真的不明白我做错了什么......我知道如何使用静态变量。

标签: c++ templates


【解决方案1】:

链接器错误总是相同的错误:您的链接器没有代码。 一旦你理解了这一点,你将很容易解决链接器错误:) 在这种情况下,缺少的代码是静态变量的定义。 在您的班级中,您声明它们,但您没有定义它们。 下面是如何定义类模板的静态变量的语法: Using static variable along with templates

我认为你对这里的模板类有点搞砸了(它们是 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;
}

【讨论】:

    【解决方案2】:

    将静态headtail 指针定义为(在类之外)

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

    【讨论】:

    • 忘了我必须这样做..非常感谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多