XMVectorPermute 的 C++ 模板相关错误
C++ template related error with XMVectorPermute
我是 DirectX11 的新手,我正在尝试使使用 DirectX Legacy 编写的文件适应新的 DirectX,但我在使用模板 XMVectorPermute 时遇到了一些问题,它曾经是 Legacy 文件中的一个函数。
我正在尝试让编译器识别 DirectXMath.h
中的模板:
// General permute template
template<uint32_t PermuteX, uint32_t PermuteY, uint32_t PermuteZ, uint32_t PermuteW>
inline XMVECTOR XM_CALLCONV XMVectorPermute(FXMVECTOR V1, FXMVECTOR V2)
{
//...Definition
通过使用以下代码:
template DirectX::XMVECTOR DirectX::XMVectorPermute<PermuteXXY.i[0], PermuteXXY.i[1], PermuteXXY.i[2], PermuteXXY.i[3]>(FXMVECTOR V1, FXMVECTOR V2);
其中PermuteXXY
定义为:
static CONST DirectX::XMVECTORI32 PermuteXXY =
{
DirectX::XM_PERMUTE_0X, DirectX::XM_PERMUTE_0X, DirectX::XM_PERMUTE_0Y, DirectX::XM_PERMUTE_0W
};
但编译器或链接器无法进行匹配:
Error reported
XM_PERMUTE_...
定义为DirectXMath.h
中的一个const uint32_t
,XMVECTORI32
定义为一个并集:
union
{
int32_t i[4];
XMVECTOR v;
};
我不太擅长 C++ 模板,所以请尽可能彻底地帮助我。非常感谢!
这里有几个问题导致您的代码失败。
首先,您不能使用 XMVECTORI32
的成员向 XMVectorPermute
提供模板参数。这不是因为类型差异(XMVECTORU32
也会发生同样的事情)。我认为问题是因为数组 i
未声明为 const
,并且该值必须是常量才能用作模板参数。无论如何,VS2017拒绝编译代码。
其次,如果不为该函数提供函数体,您就无法特化该模板函数。这意味着您的第二行不完整,需要您编写一个实现才能编译。
但这并不意味着你是 SOL,只是你需要改变你的方法。如果模板参数始终是常量(在您的代码中看起来它们应该是常量),您可以定义一个函数,该函数采用两个向量参数并指定用于该特定操作的确切置换常量。
下面的代码就是一个例子:
DirectX::XMVECTOR XMVectorPermuteXXY(DirectX::FXMVECTOR V1, DirectX::FXMVECTOR V2)
{
return DirectX::XMVectorPermute<DirectX::XM_PERMUTE_0X,
DirectX::XM_PERMUTE_0X,
DirectX::XM_PERMUTE_0Y,
DirectX::XM_PERMUTE_0W>(V1, V2);
}
任何其他需要指定的操作(XYXY、ZZWW、YYWZ 等)都可以用类似的方式定义,使用指定适当模板参数的包装函数。
第二种选择是使用 XMVectorPermute
的非模板版本,它采用两个向量和四个置换常量。这个版本可能会慢一点,但允许您在 运行 时间指定置换常量。
该代码如下所示:
XMVECTOR XMVectorPermuteXXY(FXMVECTOR V1, FXMVECTOR V2)
{
return XMVectorPermute(V1, V2,
XM_PERMUTE_0X,
XM_PERMUTE_0X,
XM_PERMUTE_0Y,
XM_PERMUTE_0W);
}
根据您要迁移的代码,您需要决定您计划使用哪个版本。
我是 DirectX11 的新手,我正在尝试使使用 DirectX Legacy 编写的文件适应新的 DirectX,但我在使用模板 XMVectorPermute 时遇到了一些问题,它曾经是 Legacy 文件中的一个函数。
我正在尝试让编译器识别 DirectXMath.h
中的模板:
// General permute template
template<uint32_t PermuteX, uint32_t PermuteY, uint32_t PermuteZ, uint32_t PermuteW>
inline XMVECTOR XM_CALLCONV XMVectorPermute(FXMVECTOR V1, FXMVECTOR V2)
{
//...Definition
通过使用以下代码:
template DirectX::XMVECTOR DirectX::XMVectorPermute<PermuteXXY.i[0], PermuteXXY.i[1], PermuteXXY.i[2], PermuteXXY.i[3]>(FXMVECTOR V1, FXMVECTOR V2);
其中PermuteXXY
定义为:
static CONST DirectX::XMVECTORI32 PermuteXXY =
{
DirectX::XM_PERMUTE_0X, DirectX::XM_PERMUTE_0X, DirectX::XM_PERMUTE_0Y, DirectX::XM_PERMUTE_0W
};
但编译器或链接器无法进行匹配: Error reported
XM_PERMUTE_...
定义为DirectXMath.h
中的一个const uint32_t
,XMVECTORI32
定义为一个并集:
union
{
int32_t i[4];
XMVECTOR v;
};
我不太擅长 C++ 模板,所以请尽可能彻底地帮助我。非常感谢!
这里有几个问题导致您的代码失败。
首先,您不能使用 XMVECTORI32
的成员向 XMVectorPermute
提供模板参数。这不是因为类型差异(XMVECTORU32
也会发生同样的事情)。我认为问题是因为数组 i
未声明为 const
,并且该值必须是常量才能用作模板参数。无论如何,VS2017拒绝编译代码。
其次,如果不为该函数提供函数体,您就无法特化该模板函数。这意味着您的第二行不完整,需要您编写一个实现才能编译。
但这并不意味着你是 SOL,只是你需要改变你的方法。如果模板参数始终是常量(在您的代码中看起来它们应该是常量),您可以定义一个函数,该函数采用两个向量参数并指定用于该特定操作的确切置换常量。
下面的代码就是一个例子:
DirectX::XMVECTOR XMVectorPermuteXXY(DirectX::FXMVECTOR V1, DirectX::FXMVECTOR V2)
{
return DirectX::XMVectorPermute<DirectX::XM_PERMUTE_0X,
DirectX::XM_PERMUTE_0X,
DirectX::XM_PERMUTE_0Y,
DirectX::XM_PERMUTE_0W>(V1, V2);
}
任何其他需要指定的操作(XYXY、ZZWW、YYWZ 等)都可以用类似的方式定义,使用指定适当模板参数的包装函数。
第二种选择是使用 XMVectorPermute
的非模板版本,它采用两个向量和四个置换常量。这个版本可能会慢一点,但允许您在 运行 时间指定置换常量。
该代码如下所示:
XMVECTOR XMVectorPermuteXXY(FXMVECTOR V1, FXMVECTOR V2)
{
return XMVectorPermute(V1, V2,
XM_PERMUTE_0X,
XM_PERMUTE_0X,
XM_PERMUTE_0Y,
XM_PERMUTE_0W);
}
根据您要迁移的代码,您需要决定您计划使用哪个版本。