我想创建一个被视为笛卡尔坐标或极坐标的矢量(数学)结构。应该只有一个结构,但会自动传递给相应的函数。
我有以下代码:
struct cartesian {};
struct polar {};
template<unsigned int N, typename format = cartesian>
struct Vec
{
float v[N];
};
然而,虽然格式参数不会改变结构的内部结构,但我相信我最终会得到两种不同的类型,而不是一种。这不是必要的。我宁愿只需要以下两个函数,而不是两种不同的类型:
template <unsigned int N>
Vec<N, cartesian> nrm(Vec<N, cartesian> v)
{
return v;
}
template <unsigned int N>
Vec<N, polar> nrm(Vec<N, polar> v)
{
return v;
}
编译器根据格式模板参数确定要使用的函数。
我不确定我解释得那么好,但希望你能理解我的意思。请询问任何澄清。
有没有办法可以实现(使用模板)?
感谢。
对于R Sahu:
两个独立的功能如下:
Vec<N, cartesian> nrm(Vec<N, cartesian> v)
{
float vLen = sqrt(v[0] * v[0] + v[1] * v[1]);
Vec<N, cartesian> result = v;
result[0] /= vLen; // 0 is X
result[1] /= vLen; // 1 is Y
return result;
}
template <unsigned int N>
Vec<N, polar> nrm(Vec<N, polar> v)
{
Vec<N, polar> result = v;
result[1] = 1.0F; // 1 is length of vector
return result;
}
对不起,如果退回v;引起混淆,只是让错误检查器安静,我想删除冗长。
非模板化示例可能有所帮助:
INT CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, INT nCmdShow)
{
// I believe the code is currently being compiled down to the non-template equivalent:
// How I DON'T want it
// 2 separate type definitions
Vec2Car cartesianVec = { 1, 1 };
Vec2Pol polarVec = { 0.785F, 1.41F };
// Appropriate function is called for the type passed in
Vec2Car cartesianNrm = nrm(cartesianVec);
Vec2Pol polarNrm = nrm(polarVec);
// How I DO want it
Vec2CarPol cartesianVec = Vec<2, cartesian>(1, 1); // created with <format = cartesian>, doesn't change type definition, but compiler should know what to call below
Vec2CarPol polarVec = Vec<2, polar> ( 0.785F, 1.41F); // as above
// cartesianVec was created with <format = cartesian>, so use this the appropriate version of nrm();
Vec2CarPol cartesianNrm = nrm(cartesianVec);
// polarNrm was created with <format = polar>, so use this the appropriate version of nrm();
Vec2CarPol polarNrm = nrm(polarVec);
return EXIT_SUCCESS;
}
答案 0 :(得分:2)
只需使用一个带有两个模板参数的函数模板。
template <unsigned int N, typename format>
Vec<N, format> nrm(Vec<N, format> v)
{
return v;
}
或者,正如@cdhowie所建议的那样,使用
template <typename T>
T nrm(T v)
{
return v;
}
更新,以回应更新的问题
你的功能有点令人困惑。当你使用:
result[0] /= vLen; // 0 is X
result[1] /= vLen; // 1 is Y
你是说吗?
result.v[0] /= vLen; // 0 is X
result.v[1] /= vLen; // 1 is Y
我假设这就是你的意思。
您可以使用以下方法获得最易重复使用的代码:
template<unsigned int N, typename format = cartesian>
struct Vec
{
typedef format Format;
float v[N];
};
void nrm(float v[], cartesian dummy)
{
float vLen = sqrt(v[0] * v[0] + v[1] * v[1]);
v[0] /= vLen;
v[1] /= vLen;
}
void nrm(float v[], polar dummy)
{
v[1] = 1.0F;
}
template <typename T>
T nrm(T v)
{
T result = v;
nrm(result.v, T::Format());
// Not sure what's the purpose of computing result.
// It is not being returned.
return v;
}
答案 1 :(得分:0)
只要您将format
作为模板参数之一,编译器就会生成两个结构。它是允许编译器在编译时选择调用两个函数中的哪一个的类型。