在C接口中声明模板函数?

为了演示,想象我有一些动物类,每个都来自一个“动物”类,每个都“知道”它们是什么类型,并且每个都具有某种独特的能力:

enum class animal_type { antelope, bear, cat };

class animal
{
};

class antelope : public animal
{
public:
    static const animal_type type = animal_type::antelope;
    void run() { std::cout << "antelope runs\n"; };
};

class bear : public animal
{
public:
    static const animal_type type = animal_type::bear;
    void roar() { std::cout << "bear roars\n"; };
};

class cat : public animal
{
public:
    static const animal_type type = animal_type::cat;
    void meow() { std::cout << "cat meows\n"; };
};

现在,我希望能够根据他们的类型检索动物:

class animal_getter
{
public:
    animal& get(animal_type t)
    {
        static antelope s_antelope;
        static bear s_bear;
        static cat s_cat;

        switch (t)
        {
            case animal_type::antelope:
                return s_antelope;

            case animal_type::bear:
                return s_bear;

            case animal_type::cat:
                return s_cat;
        }
    }
};

最后,让实际的动物类型回来更好,使调用语法更好:

template<typename T>
T& get()
{
    return static_cast<T&>(get(T::type));
}

现在我可以这样写:

animal_getter ag;
ag.get<antelope>().run();

而不是更多的人:

animal_getter ag;
static_cast<antelope&>(ag.get(animal_type::antelope)).run();

我希望这没有什么不合理的.但是现在我希望能够对动物进行单元测试,所以理想情况下可以伪造animal_getter类(想象实际的实现访问数据库或者单元测试中你不想要的东西,因此假的) .因此,为’animal getter’类定义一个接口,然后创建一个实现该接口的假的将是很好的.这就是问题,可以编写这个界面吗?这不会编译:

struct IAnimalGetter
{
    virtual template<typename T> T& get() = 0;
};

是否可以挽救这个想法,或者模板函数永远不会被声明为虚拟的,以便定义包含它们的接口?

如果这个想法不是首发,那么这个问题何时开始出错?是在编写模板函数时进行自己的投射吗?我是否应该停止返回动物对象然后让调用者对演员负责?

最佳答案 模板和强制类型转换和类型标记似乎在声明的用例中没有任何用处(获取动物然后立即利用其独特的特征).

antelope& get_antelope();
bear& get_bear();
cat& get_cat();

这就是所需要的.

get_antelope().run();
get_cat().meow();

如果需要,这些功能可以是独立的或成员的,虚拟的.每个返回类型需要一个函数.这与每个返回类型的switch语句中的一个案例没有太大区别,并且在某些方面优于它.

如果由于某些未指明的原因,您确实需要功能模板,则可以基于普通函数定义一个.

 template <class A>
 A& get_animal();

 template<> antelope& get_animal<antelope>() { return get_antelope(); }
 template<> bear& get_animal<bear>() { return get_bear(); }
 template<> cat& get_animal<cat>() { return get_cat(); }
点赞