我有一个表示数学向量的类模板:
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;
};
我想对整数类型的向量进行特殊处理,因为在这种类型上不能进行向量归一化。所以我需要一个单独的(可能是专门化的)Normalize方法,它依赖于VectorT类模板的模板参数Value_T。
我尝试过以不同的方式使用模板专业化,但没有让它起作用。我是否必须将Normalize功能本身作为模板功能?目前它只是普通的成员方法。
答案 0 :(得分:3)
您可以使用标记调度技术解决此问题:
#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;
};
答案 1 :(得分:1)
您似乎希望禁止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
};
答案 2 :(得分:1)
您也可以使用std :: enable_if&lt;&gt;
#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;
}
答案 3 :(得分:1)
是的,您可以独立地专门化模板类的特定成员函数。但是,功能模板(包括成员函数模板)不允许部分特化。功能模板仅支持显式特化。您案例中的明确专业化,如下所示
// 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()
{
...
}
然而,显然初始化并不是你需要的,显然,因为你想要修复&#34;仅限类型并保持大小灵活,即您需要部分专业化。这可以使用C ++ 11的std::enable_if
功能(如其他答案中所示)以及C ++ 98的一些基本技巧来完成。
当然,如果你的类相对轻量级,即除Normalize
之外它没有太多通用代码,你可以简单地部分专门化整个类。这需要更多的打字。