如何基于模板创建不同的类实现

huangapple go评论84阅读模式
英文:

how to create diffrent class implemantations based off template

问题

以下是您提供的代码的翻译部分:

在我的animal.hpp文件中,我有这个模板类声明:

  1. enum class ANIMAL_TYPE {
  2. DOG,
  3. CAT,
  4. };
  5. template <ANIMAL_TYPE T>
  6. class animal {
  7. public:
  8. void makeSound();
  9. };

这是一个经典的示例,用于解释接口和继承,但我希望它在编译时知道,并且不是虚函数,因此我在animal.cpp文件中实现如下:

  1. template <>
  2. class Animal<ANIMAL_TYPE::DOG> {
  3. public:
  4. void makeSound() {
  5. std::cout << "woof";
  6. }
  7. };
  8. template <>
  9. class Animal<ANIMAL_TYPE::CAT> {
  10. public:
  11. void makeSound() {
  12. std::cout << "MEOW";
  13. }
  14. };
  15. template class Animal<ANIMAL_TYPE::DOG>;
  16. template class Animal<ANIMAL_TYPE::CAT>;

然后,在主文件中,我这样使用它:

  1. #include <animal.hpp>
  2. int main() {
  3. Animal<ANIMAL_TYPE::DOG> doggy;
  4. doggy.makeSound();
  5. return 0;
  6. }

但是,当我编译和链接时,我得到了一个链接错误:"undefined reference to Animal<(ANIMAL_TYPE)0>::makeSound"。

英文:

Let's say I have this template class declared in my animal.hpp file:

  1. enum class ANIMAL_TYPE{
  2. DOG,
  3. CAT,
  4. };
  5. template &lt;ANIMAL_TYPE T&gt;
  6. class animal{
  7. public:
  8. void makeSound();
  9. };

Pretty classic example used in explanations of interfaces and inheritance, but I want it to be known at compile time, and not be a virtual function, so I implemented it like this in the animal.cpp file:

  1. template &lt;&gt;
  2. class Animal&lt;ANIMAL_TYPE::DOG&gt;{
  3. public:
  4. void makeSound(){
  5. std::cout &lt;&lt; &quot;woof&quot;;
  6. }
  7. };
  8. template &lt;&gt;
  9. class Animal&lt;ANIMAL_TYPE::CAT&gt;{
  10. public:
  11. void makeSound(){
  12. std::cout &lt;&lt; &quot;MEOW&quot;;
  13. }
  14. };
  15. template class Animal&lt;ANIMAL_TYPE::DOG&gt;;
  16. template class Animal&lt;ANIMAL_TYPE::CAT&gt;;

And this in the main file:

  1. #include &lt;animal.hpp&gt;
  2. int main(){
  3. Animal&lt;ANIMAL_TYPE::DOG&gt; doggy;
  4. doggy.makeSound();
  5. return 0;
  6. }

But when I compile and link this, I get an error during linking "undefined reference to Animal&lt;(ANIMAL_TYPE)0&gt;::makeSound"

答案1

得分: 0

以下是翻译的内容:

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

  1. template <typename>
  2. class Animal<ANIMAL_TYPE::DOG>{
  3. public:
  4. void makeSound(){
  5. std::cout << "woof";
  6. }
  7. };
  8. template <typename>
  9. class Animal<ANIMAL_TYPE::CAT>{
  10. public:
  11. void makeSound(){
  12. std::cout << "MEOW";
  13. }
  14. };

您应该这样做:

  1. template <>
  2. void Animal<ANIMAL_TYPE::DOG>::makeSound()
  3. {
  4. std::cout << "woof";
  5. }
  6. template <>
  7. void Animal<ANIMAL_TYPE::CAT>::makeSound()
  8. {
  9. std::cout << "MEOW";
  10. }

此外,我注意到您在animal.cpp底部有以下内容:

  1. template class Animal<ANIMAL_TYPE::DOG>;
  2. template class Animal<ANIMAL_TYPE::CAT>;

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

编辑: 好的,如果您想要有两个模板参数,一个是类型,一个不是类型,您需要在头文件中直接实例化类,因为它仍然是一个模板,而不是一个完整的实例化。

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

  1. template <ANIMAL_TYPE T, typename R>
  2. class Animal{
  3. public:
  4. void makeSound(R foo);
  5. };

您将不得不像这样实例化它(请记住将其放在头文件中,因为它仍然是一个模板,而不是一个完整的实例化)。

  1. template <typename R>
  2. class Animal<ANIMAL_TYPE::DOG, R>{
  3. public:
  4. void makeSound(R foo)
  5. {
  6. std::cout << "woof";
  7. }
  8. };
  9. template <typename R>
  10. class Animal<ANIMAL_TYPE::CAT, R>{
  11. public:
  12. void makeSound(R foo)
  13. {
  14. std::cout << "MEOW";
  15. }
  16. };

希望这对您有所帮助。

英文:

Instead of instantiating the classes themselves, you should be instantiating the methods. In other words, instead of doing this:

  1. template &lt;&gt;
  2. class Animal&lt;ANIMAL_TYPE::DOG&gt;{
  3. public:
  4. void makeSound(){
  5. std::cout &lt;&lt; &quot;woof&quot;;
  6. }
  7. };
  8. template &lt;&gt;
  9. class Animal&lt;ANIMAL_TYPE::CAT&gt;{
  10. public:
  11. void makeSound(){
  12. std::cout &lt;&lt; &quot;MEOW&quot;;
  13. }
  14. };

You should be doing this:

  1. template &lt;&gt;
  2. void Animal&lt;ANIMAL_TYPE::DOG&gt;::makeSound()
  3. {
  4. std::cout &lt;&lt; &quot;woof&quot;;
  5. }
  6. template &lt;&gt;
  7. void Animal&lt;ANIMAL_TYPE::CAT&gt;::makeSound()
  8. {
  9. std::cout &lt;&lt; &quot;MEOW&quot;;
  10. }

Also, I've noticed that you have this at the bottom of animal.cpp.

  1. template class Animal&lt;ANIMAL_TYPE::DOG&gt;;
  2. template class Animal&lt;ANIMAL_TYPE::CAT&gt;;

Those have no effect in this case, you can just remove them.

EDIT: Okay, so if you want to have two template arguments, one of which is a type, and one that is not a type, you will need to directly instantiate the class, in the header because it's still a template, not a complete instantiation.

For example, let's say that the Animal class from before takes in a type argument.

  1. template &lt;ANIMAL_TYPE T, typename R&gt;
  2. class Animal{
  3. public:
  4. void makeSound(R foo);
  5. };

You will have to instantiate it like this (Remember to put this in the header file, as it is still a template and not a complete instantiation).

  1. template &lt;typename R&gt;
  2. class Animal&lt;ANIMAL_TYPE::DOG, R&gt;{
  3. public:
  4. void makeSound(R foo)
  5. {
  6. std::cout &lt;&lt; &quot;woof&quot;;
  7. }
  8. };
  9. template &lt;typename R&gt;
  10. class Animal&lt;ANIMAL_TYPE::CAT, R&gt;{
  11. public:
  12. void makeSound(R foo)
  13. {
  14. std::cout &lt;&lt; &quot;MEOW&quot;;
  15. }
  16. };

Hopefully, this is helpful.

huangapple
  • 本文由 发表于 2023年7月31日 22:55:44
  • 转载请务必保留本文链接:https://go.coder-hub.com/76804826.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定