请考虑以下代码:
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
中引用
答案 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();
}