c++ - 静态 const 成员变量的部分特化

标签 c++ static constants partial-specialization template-classes

目前,我已经实现了一个模板类 Mat,它是第三方库矩阵类的包装器(T 是组件的类型:double、int 等)。现在,我希望实现一个 Tensor 类,使用一个 Mat 用于存储,另一个 Mat 用于映射索引。

我已将 Tensor 类模板化为 Tensor,其中 T 与 Mat 类相同,Order 和 Dim 是整数,是张量的阶数(或等级)和维数(2 或 3)。 Sym 是对称的 bool 标志。

Tensor 类将使用 Voigt 表示法将高阶张量压缩到矩阵上(例如,3×3×3×3 张量可以映射到 6×6 矩阵; 这是通过将每对索引映射到单个索引来完成的)。在 Voigt 表示法中,可以将 3×3 张量映射到 6×1 vector (矩阵),但将张量中的 (0,0) 分量移动到 vector 中的 0 位置。 similar (1,1) -> 1, (2,2) -> 2, (1,2)-> 3, (0,2)-> 4, and (0,1)-> 5. 类似的规则退出 2×2 张量(它们映射到 3×1 矩阵)。

为此,我希望我的 Tensor 类拥有矩阵:

0 5 4
5 1 3
4 3 2

如果 Dim == 3 且 Sym == true。非对称张量和二维张量都有相应的映射(共 4 个)。这些不依赖于其他模板参数(T 和 Order)。

因此,我应该在什么时候专门化它们? (在这里,这个问题适用于任何拥有模板化类的人,该类需要静态 const 成员来仅部分特化)。

我在这里检查了这个问题:Where to define static const member variables of a template class .但它没有讨论部分特化。

到目前为止,我在同一个头文件中有一个前向声明和一个类定义:

//cl_Tensor.hpp
namespace myNamespace
{
template< typename T, int Order, int Dim, bool Sym >
class Tensor;
}

template< typename T, int Order, int Dim, bool Sym >
class myNamespace::Tensor
{
protected:
    myNamespace::Mat< T> mMat; // storage
    static const myNamespace::Mat < uint > mTensorMap;

public:
// member functions and the like...
}

在我的 Tensor 类的单元测试中,我可以输入:

template<> const moris::Mat< moris::uint> moris::Tensor< moris::real, 1, 2, true>::mTensorMap = { { 0, 2}, {2, 1} };
template<> const moris::Mat< moris::uint> moris::Tensor< moris::real, 1, 2, false>::mTensorMap = { { 0, 3}, {2, 1} };
template<> const moris::Mat< moris::uint> moris::Tensor< moris::real, 1, 3, true>::mTensorMap = { { 0, 5, 4}, {5, 1, 3}, {4, 3, 2} };
template<> const moris::Mat< moris::uint> moris::Tensor< moris::real, 1, 3, false>::mTensorMap = { { 0, 5, 4}, {8, 1, 3}, {7, 6, 2} };

问题是我必须为每个订单(1、2、3 和 4)执行此操作。如果我有其他类型的张量(这里,real 是 long double 的 typdef),我将有太多重复代码。

那么我可以在哪里初始化 map ?

最佳答案

您不能部分特化类模板的静态数据成员,但您可以像您在问题中所说的那样显式特化它们。但是没有什么可以阻止您将定义外包给其他一些函数模板:

namespace myNamespace {
    template< typename T, int Order, int Dim, bool Sym >
    const Tensor<T, Order, Dim, bool>::Mat<Dim> mTensorMap = 
        TensorMapCreator<T, Order, Dim, Sym>::makeMap();
}

然后只需创建一个带有静态成员函数 makeMap() 的类模板 TensorMapCreator 即可,您可以根据自己的具体需要对其进行部分专门化做:

template <typename T, int Order, int Dim, bool Sym>
struct TensorMapCreator;

template <typename T, int Order, bool Sym>
struct TensorMapCreator<T, Order, 2, Sym> {
    static Mat<2> makeMap(); 
};

template <typename T, int Order, bool Sym>
struct TensorMapCreator<T, Order, 3, Sym> {
    static Mat<3> makeMap(); 
};

// etc.

关于c++ - 静态 const 成员变量的部分特化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31545132/

相关文章:

c++ - 如何使用 C++ 生成器获取电子邮件正文

c++ - boost::buffer 和 boost::async_write

c++ - Windows 的原始鼠标输入

c - 重构全局到局部。它们是否应该是静态的?

c++ - Const 改变变量值

c++ - 在 C 和 C++ 中使用 const 限定符指向数组的指针

c++ - 无法解释以下 C++ 片段的输出

c++ - 在类中初始化静态 vector 最方便的方法是什么?

java - OpenCV Android 上的静态初始化

java - 根据最佳实践,我应该在哪里放置用于 GUI 测量的 JavaFX 常量?