【问题标题】:Accessing template constructor and function, both static and non-static访问模板构造函数和函数,包括静态和非静态的
【发布时间】:2013-03-25 18:21:19
【问题描述】:

我是模板新手,发现这个东西相当混乱。我有一个模板类,用作将实体映射到字符串的表,我的类代码是这样的

template<class GENERIC_ENTITY> class EntityTable
{
private:

    map<wstring, GENERIC_ENTITY*> entityTable;

    // I want to put init in the default constructor so it gets initialized, but this doesn't compile 
    EntityTable<GENERIC_ENTITY>::EntityTable () {
        init();
    }

    void init()
    {
            entityTable[L"Entity1"] = new Entity1();
            entityTable[L"Entity2"] = new Entity2();
            entityTable[L"Entity3"] = new Entity3();
    }

public:

    // This function doesn't compile unless I remove the keyword static
    static template <class GENERIC_ENTITY> GENERIC_ENTITY retriveEntity(wstring identifier)
    {
        return entityTable[identifier];
    }
};

然后我想在另一个类中调用这个模板函数并使用wstring 标识符检索相应的实体。但不幸的是,我既不能构造类也不能调用这个函数,不管函数是否是静态的。它甚至不编译。

如果函数是静态的,我想做EntityTable&lt;T&gt;::retriveEntity(wstring) 之类的事情,如果不是静态的,我想先实例化它,但我不知道如何用模板来做,因为我听说模板不是一个类。我将它声明为堆栈上的实际数据,因此我不必在我不知道它是什么样的构造函数上调用 new,但我仍然无法访问该函数。

我完全糊涂了,有人能帮我解决一下吗?

编辑:

顺便说一句,我在另一个类中声明这个模板的方式是template&lt;class GENERIC_BOT&gt; EntityTable entityTable;。不知道这是否正确

所有实体类都继承自两个公共类(纠正了一个的错误),但这些类是抽象的,所以我不能通过像Entity retrieveEntity(wstring info)这样的事情来实例化它

我希望这个类是一个单例,在它被初始化的地方构造一次,并在任何地方调用静态函数。地图在构建后是不可变的。 wstring 被传递给模板,模板将返回与 wstring 标记关联的相应类。我只需要一种快速的检索方式,考虑到桌子很大的情况,为了方便,我只显示了两个项目。

附: 我知道我也可以使用 if 或 switch 语句返回相应的类型,但这又长又麻烦,并且违背了使用映射的目的

【问题讨论】:

  • Entity1Entity2Entity3 都派生自某个公共父类吗?我有一种感觉,他们没有,您正在尝试使用模板将不同类型的对象放入std::map
  • 它不能是static,因为它正在访问一个成员变量。如果你为了调用retrieveEntity()而即时构造一个EntityTable的实例,那么它的entityTable就已经是空的了。你到底想在这里做什么?如果有帮助,请摆脱 template 并使用已知值类型定义此类,然后看看您所做的是否有意义。
  • entityTable 不是 EntityTable 的静态成员,因此不能在静态方法中使用它。
  • @sftrabbit 它们都继承自一个公共类,但该类是抽象的,所以我无法通过像Entity retrieveEntity(wstring info)这样的操作来实例化它
  • retriveEntity 的签名错误。它必须返回 GENERIC_TEMPLATE* 而不是 GENERIC_TEMPLATE。除此之外,模板是错误的,因为您在类体内声明了函数。并且不确定这一点:静态修饰符必须出现在模板之后(通常您会以某种方式格式化您的代码,即模板位于实际函数签名上方的一行)。我认为您无法在静态方法中访问非静态成员。

标签: c++ templates static


【解决方案1】:

这应该可以正常编译:

template<class GENERIC_ENTITY> class EntityTable
{
private:

    map<wstring, GENERIC_ENTITY*> entityTable;

    EntityTable::EntityTable () {
        init();
    }

    void init()
    {
            entityTable[L"Entity1"] = new Entity1();
            entityTable[L"Entity2"] = new Entity2();
            entityTable[L"Entity3"] = new Entity3();
    }

public:

    GENERIC_ENTITY* retriveEntity(wstring identifier)
    {
        return entityTable[identifier];
    }
};

如果您希望它是静态的,只需应用单例模式或将 entityTable 声明为静态。但是,在这种情况下,不应该有任何构造函数可用,并且 init() 也必须是静态的,并且在代码中的某个位置调用。单例会保证 init() 只被调用一次。

【讨论】:

    猜你喜欢
    • 2012-12-10
    • 2015-06-28
    • 2010-09-12
    • 2011-03-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-07
    • 2014-03-14
    相关资源
    最近更新 更多