Template-specialization 用于 C++ 中的多个模板之一
Template-specialization for one out of multiple templates in C++
header mycomputationclass.h
:
#pragma once
template<typename numberType, bool increaseByOne>
class MyComputationClass
{
numberType a = 1;
numberType b = 2;
numberType compute();
};
#include mycomputationclass.hpp
header实现文件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()
^
我找到的所有与专业化相关的主题都只使用一个模板。有人可以帮我吗?
首先请看Why can templates only be implemented in the header file?。现在,您的问题并非源于上述,但是您应该认真考虑是否确实要在 cpp 文件中实现模板。我怀疑你没有。
无论如何,您问的问题是您正在尝试定义一种您尚未专门化的专门化 class 模板的方法。
这里有几个选项。
可以特化class模板,重复全身
template<typename numberType>
class MyComputationClass<numberType, true>
{
numberType a = 1;
numberType b = 2;
numberType compute();
};
您可以使用所有通用代码创建基本 class 模板,并派生 classes 模板,其中仅包含您需要专门化的部分
在 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;
}
header mycomputationclass.h
:
#pragma once
template<typename numberType, bool increaseByOne>
class MyComputationClass
{
numberType a = 1;
numberType b = 2;
numberType compute();
};
#include mycomputationclass.hpp
header实现文件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()
^
我找到的所有与专业化相关的主题都只使用一个模板。有人可以帮我吗?
首先请看Why can templates only be implemented in the header file?。现在,您的问题并非源于上述,但是您应该认真考虑是否确实要在 cpp 文件中实现模板。我怀疑你没有。
无论如何,您问的问题是您正在尝试定义一种您尚未专门化的专门化 class 模板的方法。
这里有几个选项。
可以特化class模板,重复全身
template<typename numberType> class MyComputationClass<numberType, true> { numberType a = 1; numberType b = 2; numberType compute(); };
您可以使用所有通用代码创建基本 class 模板,并派生 classes 模板,其中仅包含您需要专门化的部分
在 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; }