【问题标题】:Static member definition of template superclass模板超类的静态成员定义
【发布时间】:2016-04-12 14:53:01
【问题描述】:

我需要将(几个)类的实例关联到小整数,我称之为句柄

我不喜欢使用预处理器宏来做这件事,所以我想我会使用模板和多重继承。

我这样定义了一个Handle 类:

#include <map>

template<typename Key, typename Self>
class Handle
{
protected:
    static Key nextHandle;
    static std::map<Key, Self*> handles;
    Key handle;
public:
    Handle()
    {
        handles[nextHandle++] = this;
    }

    virtual ~Handle()
    {
        handles.erase(handle);
    }

    static Self * byHandle(Key handle)
    {
        typename std::map<Key, Self*>::const_iterator it = handles.find(handle);
        if(it == handles.end())
            return nullptr;
        else
            return it->second;
    }

    Key getHandle()
    {
        return handle;
    }
};

这个“模式”的用法是:

class Test : public SomeSuperclass, ... , public Handle<int, Test>
{
public:
    Test();
};

Test::Test()
    : Handle()
{
}

int Handle<int, Test>::nextHandle = 666;
std::map<int, Test*> Handle<int, Test*>::handles;

问题出在这里^^^我不知道如何定义这些静态变量的存储,我从clang++得到这个错误:

handle_test.cpp:17:24: 错误:模板专业化需要'模板'

int Handle::nextHandle = 666;

或者,如果我尝试在 Test 类中定义它,例如:

int Test::nextHandle = 666;
std::map<int, Test*> Test::handles;

我收到另一个错误:

handle_test.cpp:20:11: 错误:“测试”中没有名为“nextHandle”的成员

int 测试::nextHandle = 666;

【问题讨论】:

    标签: c++ templates


    【解决方案1】:

    如果你想要模板特化的静态成员定义,你可以:

    template<>
    int Handle<int, Test>::nextHandle = 666;
    template<>
    std::map<int, Test*> Handle<int, Test>::handles;
    

    如果您想要主模板的静态成员定义,您可以:

    template<typename Key, typename Self>
    Key Handle<Key, Self>::nextHandle;
    template<typename Key, typename Self>
    std::map<Key, Self*> Handle<Key, Self>::handles;
    

    您无法在派生类Test 上定义它们,它们是Handle 的成员。

    【讨论】:

    • 第一个建议的解决方案有效,但第二个看起来更好!
    • @mescalinum 这取决于你想要什么。如果您在代码中同时给出两者,那么在正常情况下,将使用主要版本,例如对于Handle&lt;int, int&gt;Handle&lt;float, int&gt; 等。对于特殊情况,将使用专业化版本,即Handle&lt;int, Test&gt;。如果您不需要特殊情况,那么只需提供主要版本就足够了。
    猜你喜欢
    • 2017-10-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-13
    • 1970-01-01
    相关资源
    最近更新 更多