c++ 如何基于提供模板创建不同类实现

vngu2lb8  于 2023-08-09  发布在  其他
关注(0)|答案(1)|浏览(111)

假设我在animal.hpp文件中声明了这个模板类:

enum class ANIMAL_TYPE{
     DOG,
     CAT,
};

template <ANIMAL_TYPE T>
class animal{
public:
    void makeSound();
    };

字符串
在解释接口和继承时使用的非常经典的例子,但我希望它在编译时就知道,而不是一个虚函数,所以我在animal.cpp文件中实现了它:

template <>
class Animal<ANIMAL_TYPE::DOG>{
public:
    void makeSound(){
         std::cout << "woof";
    }
};

template <>
class Animal<ANIMAL_TYPE::CAT>{
public:
    void makeSound(){
         std::cout << "MEOW";
    }
};

template class Animal<ANIMAL_TYPE::DOG>;
template class Animal<ANIMAL_TYPE::CAT>;


在主文件中:

#include <animal.hpp>

int main(){
    Animal<ANIMAL_TYPE::DOG> doggy;
    doggy.makeSound();
    return 0;
}


但是当我编译并链接它时,我在链接“undefined reference to Animal<(ANIMAL_TYPE)0>::makeSound”时得到一个错误。

wa7juj8i

wa7juj8i1#

您应该示例化方法,而不是示例化类本身。换句话说,与其这样做:

template <>
class Animal<ANIMAL_TYPE::DOG>{
public:
    void makeSound(){
         std::cout << "woof";
    }
};

template <>
class Animal<ANIMAL_TYPE::CAT>{
public:
    void makeSound(){
         std::cout << "MEOW";
    }
};

字符串
你应该这样做:

template <>
void Animal<ANIMAL_TYPE::DOG>::makeSound()
{
    std::cout << "woof";
}

template <>
void Animal<ANIMAL_TYPE::CAT>::makeSound()
{
    std::cout << "MEOW";
}


另外,我注意到在animal.cpp的底部有这个。

template class Animal<ANIMAL_TYPE::DOG>;
template class Animal<ANIMAL_TYPE::CAT>;


在这种情况下,它们没有任何效果,您可以删除它们。

**EDIT:**好的,所以如果你想有两个模板参数,一个是类型,一个不是类型,你需要直接示例化类,在头部因为它仍然是一个模板,而不是一个完整的示例化。

例如,假设前面的Animal类接受了一个类型参数。

template <ANIMAL_TYPE T, typename R>
class Animal{
    public:
    void makeSound(R foo);
};


你必须像这样示例化它(记住把它放在头文件中,因为它仍然是一个模板,而不是一个完整的示例化)。

template <typename R>
class Animal<ANIMAL_TYPE::DOG, R>{
    public:
    void makeSound(R foo)
    {
        std::cout << "woof";
    }
};

template <typename R>
class Animal<ANIMAL_TYPE::CAT, R>{
    public:
    void makeSound(R foo)
    {
        std::cout << "MEOW";
    }
};


希望这对你有帮助。

相关问题