【问题标题】:how to automate template typename specification with CLASSNAME<typename>(argument);如何使用 CLASSNAME<typename>(argument) 自动化模板类型名规范;
【发布时间】:2011-04-28 21:07:42
【问题描述】:

我正在为游戏世界中的某些对象创建一个统计编辑器。我没有为每种对象类型设置多个编辑菜单,而是只有一个菜单,并传入一个 stat-edit-objects 列表/向量,其中包含指向正在编辑的 stat 的指针,以及完成工作的函数。

struct StatEditObjPureBase
{
    std::vector<std::string> reps;
    std::string name;
    std::basic_string<int> value;
    const iWindow* win;
    Editor* pE;

    StatEditObjPureBase(iWindow& rIW, Editor& rE) : win(&rIW), pE(&rE) {}

    virtual ~StatEditObjPureBase() = 0;
    virtual StatEditObjPureBase* clone() = 0;
    virtual void set() = 0;
    virtual void dec() = 0;
    virtual void inc() = 0;
    virtual void update() = 0;
};

struct StatEditObjWrap
{
    StatEditObjPureBase* base;

    StatEditObjWrap(StatEditObjPureBase* p) : base(p) {}
    StatEditObjWrap(const StatEditObjWrap& that) { base = that.base->clone(); }
    ~StatEditObjWrap() { delete base; }
};

template<class T> struct StatEditObj_INT : StatEditObjPureBase
{
    T* pMain;

    StatEditObj_INT(T* p, iWindow& rIW, Editor& rE) : StatEditObjPureBase(rIW, rE), pMain(p) {}
    StatEditObj_INT* clone() { return new StatEditObj_INT(*this); }
    void set();
    void dec(){--(*pMain);}
    void inc(){++(*pMain);}
    void update();
};

template<class T> void StatEditObj_INT<T>::set()
{
    *pMain = input_getInt(win->box_input_y, win->box_input_x, win->box_input_range, win->box_input_fg, win->box_input_bg);
}

template<class T> void StatEditObj_INT<T>::update()
{
    staticStatEditObj_intUpdate(*pMain, value, reps);
}

我的主要问题是必须指出其指针存储在模板派生类中的变量的类型。以下代码是一个小示例,但您可以假设会有数百个这样的 stat 编辑对象条目:

void Editor::statEditObjectTemplate(ObjectTemplate& r)
{
    std::vector<iWindowEntry> temp;
    iWindow iw(17, 60, temp);

    std::vector<StatEditObjWrap> stats;

    { StatEditObjWrap stat(new StatEditObj_INT<unsigned short>(&r.glyph, iw, *this)); stats.push_back(stat); }
    { StatEditObjWrap stat(new StatEditObj_INT<unsigned int>(&r.mappedFcolour, iw, *this)); stats.push_back(stat); }
    { StatEditObjWrap stat(new StatEditObj_INT<unsigned int>(&r.mappedBcolour, iw, *this)); stats.push_back(stat); }

    statEditor(stats, iw);
}

有没有办法为

设置模板类型名
new StatEditObj_INT<type>(&r.variable, iw, *this)

自动通过?

(注:类型为StatEditObj_INT的构造函数的第一个参数)

【问题讨论】:

    标签: c++ templates derived-class


    【解决方案1】:

    是的,你可以使用工厂函数:

    // Note:  Callee takes ownership of returned pointer
    // (Alternatively, you should consider using a smart pointer like shared_ptr)
    template <typename T>
    StatEditObj_INT<T>* MakeNew_StatEditObj_INT(T* p, iWindow& rIW, Editor& rE)
    {
        return new StatEditObj_INT<T>(p, rIW, rE);
    }
    

    那么你有:

    stats.push_back(MakeNew_StatEditObj_INT(&r.glyph, iw, *this));
    stats.push_back(MakeNew_StatEditObj_INT(&r.mappedFcolour, iw, *this));
    stats.push_back(MakeNew_StatEditObj_INT(&r.mappedBcolour, iw, *this));
    

    这是有效的,因为当您使用函数模板时,编译器可以从函数参数中推断出模板参数(显然在某些情况下它不能,例如,如果您有一个未在函数中表示的模板参数参数列表或仅在非推导上下文中表示)。这是处理类模板时的常见习语。

    【讨论】:

    • 在 OP 给出的示例代码中,他不能只是省略类型并让编译器确定它吗(你在这里用MakeNew_StatEditObj_INT 做了多少?
    • @JoshD:不,因为你必须在新表达式中指定类型名称;编译器无法从构造函数调用中推断出类模板参数。
    • 谢谢。我不知道。
    【解决方案2】:

    在非模板类中使用模板成员函数。

    struct StatEditObjWrap
    {
      template <typename T>
      static StatEditObjWrap create(T* p, iWindow& rIW, Editor& rE);
    
      //...
    }
    
    template <typename T>
    StatEditObjWrap StatEditObjWrap::create<T>(T* p, iWindow& rIW, Editor& rE) {
      return StatEditObjWrap( new StatEditObj_INT<T>( p, rIW, rE ) );
    }
    
    {
      vector<StatEditObjWrap> stats;
      stats.push_back(StatEditObjWrap::create(&r.glyph, iW, *this));
    }
    

    【讨论】:

      猜你喜欢
      • 2019-02-26
      • 1970-01-01
      • 1970-01-01
      • 2015-05-12
      • 2021-04-11
      • 1970-01-01
      • 2017-06-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多