首页 > 解决方案 > C++ 中多个模板之一的模板专业化

问题描述

标题mycomputationclass.h

#pragma once
template<typename numberType, bool increaseByOne>
class MyComputationClass
{
   numberType a = 1;
   numberType b = 2;
   numberType compute();
};

#include mycomputationclass.hpp

头实现文件mycomputationclass.hpp

#pragma once
#include mycomputationclass.h

template<typename numberType, bool increaseByOne>
numberType MyComputationClass<numberType, increaseByOne>::compute()
{
   return a + b;
}
template<typename numberType>
numberType MyComputationClass<numberType, true>::compute()
{
   return a + b + static_cast<numberType>(1);
}

错误:

 error: invalid use of incomplete type ‘class MyComputationClass<numberType, true>’
 numberType MyComputationClass<numberType, true>::compute()
                                                          ^

我发现的所有与专业化相关的主题都只使用一个模板。任何人都可以在这里帮助我吗?

标签: c++templatestemplate-specialization

解决方案


首先请看为什么模板只能在头文件中实现?. 现在,您的问题并非源于上述问题,但是您应该认真考虑是否确实要在 cpp 文件中实现模板。我怀疑你没有。

无论如何,您要问的问题是您正在尝试定义您尚未专门化的专门类模板的方法。

这里有几个选项。

  • 您可以专门化类模板,重复整个身体

    template<typename numberType>
    class MyComputationClass<numberType, true>
    {
       numberType a = 1;
       numberType b = 2;
       numberType compute();
    };
    
  • 您可以创建包含所有公共代码的基类模板,并拥有仅包含您需要专门化的部分的派生类模板

  • 在 C++17 中,您可以使用if constexpr

    template<typename numberType, bool increaseByOne>
    numberType MyComputationClass<numberType, increaseByOne>::compute()
    {
        if constexpr (increateByOne)
            return a + b + 1;
        else
            return a + b;
    }
    
  • 在 C++20 中,您可以使用 requires 子句:

    template<typename numberType, bool increaseByOne>
    class MyComputationClass
    {
       numberType a = 1;
       numberType b = 2;
       numberType compute() requires increaseByOne
       {
           return a + b + 1;
       };
        numberType compute() requires (!increaseByOne)
       {
           return a + b;
       };
    };
    
  • 在您的情况下,在旧 C++ 中,您可以使用简单的 if。由于increaseByOne在编译时已知,编译器会将其优化为if constexpr. 您将遇到的唯一问题是,如果您在每个分支上返回了不同的类型,或者在其中一个分支上有一些无效的代码。if这里的解决方案非常简单:

    template<typename numberType, bool increaseByOne>
    numberType MyComputationClass<numberType, increaseByOne>::compute()
    {
        if (increateByOne)
            return a + b + 1;
        else
            return a + b;
    }
    

推荐阅读