使用名称空间作为参数的模板函数?
Template functions using namespace as parameter?
出于性能原因,我必须使用显式操作来制作自己的 类 向量、矩阵、张量等。因为我只使用 2D 或 3D 维度,所以我为每个维度定义了 类 使用命名空间。这是代码的简单草稿:
namespace Dim2 {
class Vec {
public:
double components[2];
};
class Mat {
public:
double components[2][2];
};
}
namespace Dim3 {
class Vec {
public:
double components[3];
};
class Mat {
public:
double components[3][3];
};
}
所以如果我需要,例如,一个 3D 矢量,我调用 Dim3::Vec newVec;
,我可以执行针对 3 维优化的操作。
现在,假设我想使用如下模板编写通用函数:
template<typename Vec, typename Mat>
void doSomething()
{
Vec v;
Mat m;
// Perform operations
}
这样,如果我想使用 2D 向量,我调用 doSomething<Dim2::Vec, Dim2::Mat>();
,对于 3D 向量:doSomething<Dim3::Vec, Dim3::Mat>();
.
此解决方案也在 中得到解决,并且工作正常。问题是…… 'real' 代码不仅有向量和矩阵,还有无数其他结构:三阶张量、四阶张量、对称矩阵等。如果我在函数中使用所有这些,调用将是这样的:
doSomething<Dim2::Vec, Dim2::Mat, Dim3::Tensor3, Dim3::Tensor4, Dim4:: SymMat, ...>();
太广泛(而且丑陋)。
为了简短起见,我真正想做的是将命名空间作为模板参数。像这样:
template<typename Dim>
void doSomething()
{
Dim::Vec v;
Dim::Mat m;
Dim::Tensor3 t3;
Dim::Tensor4 t4;
Dim::SymMat symMat;
// Perform operations
}
这样,函数调用将很简单 doSomething<Dim2>();
或 doSomething<Dim3>();
。
但是,这样做会给我一个编译器错误,因为 C++ 不允许名称空间作为模板参数。我尝试使用嵌套 类(即 Dim2
和 Dim3
作为 类,而不是名称空间)来做同样的事情,但我仍然遇到编译器错误。
我该怎么做才能完成我想做的事情?你们有其他选择吗?
在此先感谢,对于任何英语错误,我们深表歉意。
您可以使用类型 traits-like 帮助程序 struct
s 来减少用于调用 doSomething()
.
的参数数量
namespace Dim2 {
class Vec {
public:
double components[2];
};
class Mat {
public:
double components[2][2];
};
struct Chooser
{
using Vec = Vec;
using Mat = Mat;
};
}
namespace Dim3 {
class Vec {
public:
double components[3];
};
class Mat {
public:
double components[3][3];
};
struct Chooser
{
using Vec = Vec;
using Mat = Mat;
};
}
template <typename Chooser>
void doSomething()
{
using Vec = typename Chooser::Vec;
using Mat = typename Chooser::Mat;
Vec v1;
Mat m1;
}
int main()
{
doSomething<Dim2::Chooser>();
doSomething<Dim3::Chooser>();
}
出于性能原因,我必须使用显式操作来制作自己的 类 向量、矩阵、张量等。因为我只使用 2D 或 3D 维度,所以我为每个维度定义了 类 使用命名空间。这是代码的简单草稿:
namespace Dim2 {
class Vec {
public:
double components[2];
};
class Mat {
public:
double components[2][2];
};
}
namespace Dim3 {
class Vec {
public:
double components[3];
};
class Mat {
public:
double components[3][3];
};
}
所以如果我需要,例如,一个 3D 矢量,我调用 Dim3::Vec newVec;
,我可以执行针对 3 维优化的操作。
现在,假设我想使用如下模板编写通用函数:
template<typename Vec, typename Mat>
void doSomething()
{
Vec v;
Mat m;
// Perform operations
}
这样,如果我想使用 2D 向量,我调用 doSomething<Dim2::Vec, Dim2::Mat>();
,对于 3D 向量:doSomething<Dim3::Vec, Dim3::Mat>();
.
此解决方案也在
doSomething<Dim2::Vec, Dim2::Mat, Dim3::Tensor3, Dim3::Tensor4, Dim4:: SymMat, ...>();
太广泛(而且丑陋)。
为了简短起见,我真正想做的是将命名空间作为模板参数。像这样:
template<typename Dim>
void doSomething()
{
Dim::Vec v;
Dim::Mat m;
Dim::Tensor3 t3;
Dim::Tensor4 t4;
Dim::SymMat symMat;
// Perform operations
}
这样,函数调用将很简单 doSomething<Dim2>();
或 doSomething<Dim3>();
。
但是,这样做会给我一个编译器错误,因为 C++ 不允许名称空间作为模板参数。我尝试使用嵌套 类(即 Dim2
和 Dim3
作为 类,而不是名称空间)来做同样的事情,但我仍然遇到编译器错误。
我该怎么做才能完成我想做的事情?你们有其他选择吗?
在此先感谢,对于任何英语错误,我们深表歉意。
您可以使用类型 traits-like 帮助程序 struct
s 来减少用于调用 doSomething()
.
namespace Dim2 {
class Vec {
public:
double components[2];
};
class Mat {
public:
double components[2][2];
};
struct Chooser
{
using Vec = Vec;
using Mat = Mat;
};
}
namespace Dim3 {
class Vec {
public:
double components[3];
};
class Mat {
public:
double components[3][3];
};
struct Chooser
{
using Vec = Vec;
using Mat = Mat;
};
}
template <typename Chooser>
void doSomething()
{
using Vec = typename Chooser::Vec;
using Mat = typename Chooser::Mat;
Vec v1;
Mat m1;
}
int main()
{
doSomething<Dim2::Chooser>();
doSomething<Dim3::Chooser>();
}