如何获得专用模板以使用成员函数的非专业化版本?

时间:2008-12-07 01:43:56

标签: c++ templates specialization

请考虑以下代码:

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();
}

编译此代码会产生以下错误:

  

1&gt; main.obj:错误LNK2019:未解析的外部符号“public:struct vec&lt; 3&gt; __thiscall vec&lt; 3&gt; :: normalize(void)”(?normalize @?$ vec @ $ 02 @@ QAE?AU1 @ XZ)在函数_main

中引用

3 个答案:

答案 0 :(得分:9)

你不能:)你想要的是专门化成员函数:

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;
}

另一个稍微复杂的解决方案是使用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;
}

如果为任何dim调用cross_product,那将导致编译时错误!= 3.请注意,'trick'仅适用于带参数的函数,因为只有这样才能自动推导出模板参数。对于没有参数的情况,我提供了一个函数without_parameters :)。

答案 1 :(得分:2)

您尚未提供vec&lt; 3&gt; :: normalize的定义,因此链接器显然无法链接到它。

模板专业化的全部内容是您可以提供每种方法的专用版本。除非你在这种情况下实际上没有这样做。

答案 2 :(得分:1)

据我所知,你不能称之为“通用”版本。

或者,您可以在类之外将通用实现定义为函数:

template <int dim>
struct vec
{
};

namespace impl {
    template <int dim>
    vec<dim> normalize(const vec<dim>& v)
    {
        // code to normalize vector here
        return v;
    }
}

template <>
struct vec<3>
{
    vec cross_product(const vec& second);
    vec normalize() { return impl::normalize(*this); }
};


int main()
{
    vec<3> direction;
    direction.normalize();
}