如何获得一个专门的模板来使用成员函数的非特殊版本? [英] How can I get a specialized template to use the unspecialized version of a member function?
问题描述
请考虑以下代码:
template< int dim>
struct vec
{
vec normalize();
};
模板<>
struct vec< 3>
{
vec cross_product(const vec& second);
vec normalize();
};
template< int dim>
vec vec< dim> :: normalize()
{
//用于标准化向量的代码这里
return * this;
}
int main()
{
vec< 3>方向;
direction.normalize();
}
编译此代码会产生以下错误:
1> main.obj:error LNK2019:未解析的外部符号public:struct vec <3> __thiscall vec <3> :: normalize(void)
?$ vec @ $ 02 @@ QAE?AU1 @你不能:)你想要的是专门化的成员函数代替:
template< int dim&
struct vec
{
//除了dim == 3之外的所有函数都保留函数未定义
vec cross_product(const vec& second);
vec normalize();
};
模板<>
vec< 3> vec 3 :: cross_product(const vec& second){
// ...
}
template< int dim>
vec< dim> vec< dim> :: normalize()
{
//用于标准化向量的代码这里
return * this;
}
另一个略微更复杂的解决方案是使用 boost :: enable_if
:
模板< int dim>
struct vec
{
//函数无法调用dim!= 3.编译时出错
template< int dim1>
typename boost :: enable_if_c< dim == dim1&& dim1 == 3,vec< dim1> > :: type
cross_product(const vec< dim1& second){
// ...
}
vec normalize();
//委托给模板版本
void without_params(){
//委托
this-> without_params< dim>();
}
private:
//函数无法调用dim!= 3.编译时出错
template< int dim1>
typename boost :: enable_if_c< dim == dim1&& dim1 == 3> :: type
without_params(){
// ...
}
};
template< int dim>
vec< dim> vec< dim> :: normalize()
{
//用于标准化向量的代码这里
return * this;
}
这将导致编译时错误,如果cross_product被调用任何dim!注意,'trick'只适用于带参数的函数,因为只有那时模板参数才能被自动推导出来。对于没有参数的情况,我提供了一个函数 without_parameters
上面:)。
Consider the following code:
template <int dim>
struct vec
{
vec normalize();
};
template <>
struct vec<3>
{
vec cross_product(const vec& second);
vec normalize();
};
template <int dim>
vec<dim> vec<dim>::normalize()
{
// code to normalize vector here
return *this;
}
int main()
{
vec<3> direction;
direction.normalize();
}
Compiling this code produces the following error:
1>main.obj : error LNK2019: unresolved external symbol "public: struct vec<3> __thiscall vec<3>::normalize(void)" (?normalize@?$vec@$02@@QAE?AU1@XZ) referenced in function _main
You can't :) What you want is to specialize the member functions instead:
template <int dim>
struct vec
{
// leave the function undefined for everything except dim==3
vec cross_product(const vec& second);
vec normalize();
};
template<>
vec<3> vec<3>::cross_product(const vec& second) {
// ...
}
template <int dim>
vec<dim> vec<dim>::normalize()
{
// code to normalize vector here
return *this;
}
Another, slightly more complicated solution is to use boost::enable_if
:
template <int dim>
struct vec
{
// function can't be called for dim != 3. Error at compile-time
template<int dim1>
typename boost::enable_if_c< dim == dim1 && dim1 == 3, vec<dim1> >::type
cross_product(const vec<dim1>& second) {
// ...
}
vec normalize();
// delegate to the template version
void without_params() {
// delegate
this->without_params<dim>();
}
private:
// function can't be called for dim != 3. Error at compile-time
template<int dim1>
typename boost::enable_if_c< dim == dim1 && dim1 == 3 >::type
without_params() {
// ...
}
};
template <int dim>
vec<dim> vec<dim>::normalize()
{
// code to normalize vector here
return *this;
}
That will cause a compile time error if cross_product is called for any dim != 3. Note that that 'trick' only works for functions with parameters, since only then the template parameter can be auto-deduced. For cases without parameters, i have provided a function without_parameters
above :).
这篇关于如何获得一个专门的模板来使用成员函数的非特殊版本?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!