[英]C++ - Specialize member function for Template Class
我有一个代表数学向量的类模板:
template<class Value_T, unsigned int N>
class VectorT
{
public:
void Normalize()
{
// normalize only double/float vectors here
}
private:
// elements in the vector
value_type elements[N];
// the number of elements
static const size_type size = N;
};
我想对整数类型的向量进行特殊处理,因为在这种类型的向量上不可能进行向量归一化。 因此,我需要一个单独的(可能是专门化的)规范化方法,该方法取决于VectorT类模板的模板参数Value_T。
我试图以不同的方式使用模板专业化,但是没有使其正常工作。 我是否必须使Normalize函数本身成为模板函数? 目前,这只是正常的成员方法。
您可以使用标签分配技术解决此问题:
#include <iostream>
#include <type_traits>
template<class Value_T, unsigned int N>
class VectorT
{
public:
void Normalize()
{
using tag = std::integral_constant<bool
, std::is_same<Value_T, double>::value
|| std::is_same<Value_T, float>::value>;
// normalize only double/float vectors here
Normalize(tag());
}
private:
void Normalize(std::true_type)
{
std::cout << "Normalizing" << std::endl;
}
void Normalize(std::false_type)
{
std::cout << "Not normalizing" << std::endl;
}
// elements in the vector
Value_T elements[N];
// the number of elements
static const std::size_t size = N;
};
似乎您要禁止对除浮点以外的其他类型进行Normalize
,因此您可以使用static_assert
获得良好的错误消息:
template<class Value_T, unsigned int N>
class VectorT
{
public:
void Normalize()
{
static_assert(std::is_floating_point<Value_T>::value, "Normalize available only for floating point");
// normalize only double/float vectors here
}
// Other stuff
};
您也可以使用std :: enable_if <>
#include <iostream>
#include <type_traits>
template<class Value_T>
class VectorT
{
public:
template<class T = Value_T>
typename std::enable_if<std::is_integral<T>::value, void>::type
Normalize()
{
std::cout << "Not normalizing" << std::endl;
}
template<class T = Value_T>
typename std::enable_if<!std::is_integral<T>::value, void>::type
Normalize()
{
std::cout << "Normalizing" << std::endl;
}
};
int main()
{
VectorT<int> vint;
VectorT<double> vdouble;
vint.Normalize();
vdouble.Normalize();
return 0;
}
是的,您可以独立地专门化模板类的特定成员函数。 但是,功能模板(包括成员功能模板)不允许部分专业化 。 功能模板仅支持显式专业化 。 您的情况下的显式专业化如下所示
// Header file
template<class Value_T, unsigned int N>
class VectorT
{
public:
void Normalize()
{
// normalize only double/float vectors here
}
...
};
// Declare an explicit specialization for <int, 5>
template <> void VectorT<int, 5>::Normalize();
接着
// Implementation file
// Define the explicit specialization for <int, 5>
template <> void VectorT<int, 5>::Normalize()
{
...
}
但是,显然不需要显式初始化,因为您只想“固定”类型并保持大小灵活,即需要部分专业化。 可以使用C ++ 11的std::enable_if
功能(如其他答案所示)以及C ++ 98的一些基本技巧来完成。
当然,如果您的类相对较轻,也就是说,除了Normalize
之外,它没有太多通用代码,您可以简单地对整个类进行部分专业化处理。 这将需要更多的输入。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.