3

考虑以下代码:

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>main.obj:错误 LNK2019:引用了未解析的外部符号“public:struct vec<3> __thiscall vec<3>::normalize(void)”(?normalize@?$vec@$02@@QAE?AU1@XZ)在函数 _main

4

3 回答 3

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 != 3 调用 cross_product,这将导致编译时错误。请注意,“技巧”仅适用于带参数的函数,因为只有这样才能自动推导出模板参数。对于没有参数的情况,我在without_parameters上面提供了一个函数:)。

于 2008-12-07T01:59:10.247 回答
2

您没有提供 vec<3>::normalize 的定义,因此链接器显然无法链接到它。

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

于 2008-12-07T01:51:19.043 回答
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();
}
于 2008-12-07T01:52:36.653 回答