如何获得一个专门的模板来使用成员函数的非特殊版本? [英] How can I get a specialized template to use the unspecialized version of a member function?

查看:175
本文介绍了如何获得一个专门的模板来使用成员函数的非特殊版本?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请考虑以下代码:

  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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆