如何传入模板类型参数

时间:2014-06-24 06:08:20

标签: c++ templates

我正在与同事讨论模板问题,而我们讨论的一件事就是如下所示,如果通过使用模板获得switch语句,你将如何逃脱? / p>

enum EVersion
{
    Version_1,
    Version_2,
};

class CBar
{
    ...
public:
    EVersion ver;
};

class CFoo
{
    void Reset()
    {
        switch (pBar->ver)
        {
            case Version_1:
                TemplateHelperMethod<Version_1>::DoSomething();
            break;

            case Version_2:
                TemplateHelperMethod<Version_2>::DoSomething();
            break;
        }
    }

    CBar *pBar;
};

CFoo* pFoo = new CFoo(pBar);
pFoo->Reset();

一种解决方案是创建派生模板化类,并将函数移动到需要根据版本使用switch语句的派生类。

class CFoo
{
    ...
    CBar *pBar;
};

template <EVersion Ver>
class CFoo2 : public Foo
{
    void Reset()
    {
        TemplateHelperMethod<Ver>::DoSomething();
    }
};

CFoo2<Version_2>* pFoo = new CFoo2<Version_2>(pBar);
pFoo->Reset(); 

但是,我的同事建议可以将原始函数保留在基类中,只需将其更改为模板化方法(如下所示)。但是,我对如何运作有点密集。你现在如何使用派生类将类型传递给模板化方法?如果有人有任何想法,请告诉我。感谢。

class CFoo
{
    template <EVersion Ver>
    void Reset()
    {
        TemplateHelperMethod<Ver>::DoSomething();
    }

    CBar *pBar;
};

template <EVersion Ver>
class CFoo2 : public Foo
{
    // does anything go here?
};

CFoo2<Version_2>* pFoo = new CFoo2<Version_2>(pBar);
pFoo->Reset();

OR

CFoo* pFoo = new CFoo(pBar);
// Can you do this? since CFoo2 derives from CFoo
// and has no additional members...   
CFoo2<Version_2>* pFoo2 = static_cast<CFoo2<Version_2>*>(pFoo);
pFoo2->Reset(); 

1 个答案:

答案 0 :(得分:0)

我认为你的同事所建议的是不可能的,因为pBar->ver不是编译时常量。您不能将其用作模板参数。

删除运行时变量上的开关的正确解决方案是运行时多态

struct Version
{
    virtual ~Version() = default;
    virtual void DoSomething() = 0;
};

class CBar
{
public:
    Version& ver;
};


class CFoo
{
public:
    void Reset()
    {
        pBar->ver.DoSomething();
    }
    CBar *pBar;
};

如果你使CBar::ver为编译时常量,你可以用它来专门化CFoo

template<EVersion Version>
struct CBar
{
    EVersion version = Version;
};


template<EVersion Version>
struct CFoo
{
    void Reset();
    CBar<Version> pBar;
};


template<>
void CFoo<Version_1>::Reset()
{
}

template<>
void CFoo<Version_2>::Reset()
{
}