编译时间矩阵模板类型
Compile-time matrix template type
我正试图获得一段我为工作乐趣而编写的代码。基本上,我想生成一个类型,在编译时给出:一个矩阵。
例如,我希望abstract_matrix
如下所示:
template <std::size_t r, std::size_t c, class T = double>
class abstract_matrix
{
public:
static const std::size_t rows = r;
static const std::size_t cols = c;
typedef T value_type;
typedef T storage_type[rows][cols];
constexpr abstract_matrix(storage_type items)
{
// I hope it's not needed
}
storage_type storage;
};
然后,我想用一些魔法来创建具体类型,大致如下:
constexpr static const int vals[3][3] {
{ 1, 0, 0 },
{ 0, 1, 0 },
{ 0, 0, 1 }
};
// do magic here for the vals parameter to make this compile
using id_3by3 = abstract_matrix<3, 3, vals, int>;
// use the generated type
id_3by3 mymatrix;
auto matrix = mymatrix * ...;
关于如何将这些值">注入"到模板中并在编译时生成正确的类型,您有什么建议吗?类型中的所有内容都是static
、const
和constexpr
。
谢谢!
您可以让它发挥作用,但有几件事必须考虑。
-
vals
可以作为非类型参数传递。但是,它需要在T
之后。否则,参数的基本类型是未知的。因此,
T
没有默认值。您可能会继续将T
的默认值设为double
,并将最后一个参数的默认值设置为nullptr
,但这会导致代码混乱。 -
id_3by3
的定义需要使用&vals
,而不仅仅是vals
。 -
如果将
vals
定义为const
,则非类型模板参数的类型中也必须使用const
。const int vals[3][3] { ... };
要求您使用
template <std::size_t r, std::size_t c, class T, T const(*v)[r][c] > class abstract_matrix { ... };
如果你想修改矩阵的内容,你需要使用:
template <std::size_t r, std::size_t c, class T, T (*v)[r][c]> class abstract_matrix { ... };
它要求您使用
int vals[3][3] { ... };
这里有一个工作程序:
#include <iostream>
#include <cstdint>
template <std::size_t r, std::size_t c, class T , T (*v)[r][c]>
class abstract_matrix
{
public:
static const std::size_t rows = r;
static const std::size_t cols = c;
typedef T value_type;
constexpr static T(&vals)[r][c] = *v;
constexpr abstract_matrix()
{
}
};
int vals[3][3] {
{ 1, 0, 0 },
{ 0, 1, 0 },
{ 0, 0, 1 }
};
using id_3by3 = abstract_matrix<3, 3, int, &vals>;
int main()
{
id_3by3 mymatrix;
// Original matrix.
for ( size_t i = 0; i < id_3by3::rows; ++i )
{
for ( size_t j = 0; j < id_3by3::cols; ++j )
{
std::cout << id_3by3::vals[i][j] << " ";
id_3by3::vals[i][j]++;
}
std::cout << "n";
}
std::cout << "n";
// Modified matrix.
for ( size_t i = 0; i < id_3by3::rows; ++i )
{
for ( size_t j = 0; j < id_3by3::cols; ++j )
{
std::cout << id_3by3::vals[i][j] << " ";
}
std::cout << "n";
}
}
输出:
1 0 0
0 1 0
0 0 1
2 1 1
1 2 1
1 1 2
更新,以响应OP的命令
当您希望能够定义.h文件类型并在多个.cpp文件中使用它时,可以使用static int vals[3][3] = { ... };
。
我能够在多个.cpp文件中使用具有以下内容的.h文件。
#pragma once
#include <cstdint>
template <std::size_t r, std::size_t c, class T , T (*v)[r][c]>
class abstract_matrix
{
public:
static const std::size_t rows = r;
static const std::size_t cols = c;
typedef T value_type;
constexpr static T(&vals)[r][c] = *v;
constexpr abstract_matrix()
{
}
};
static int vals[3][3] {
{ 1, 0, 0 },
{ 0, 1, 0 },
{ 0, 0, 1 }
};
using id_3by3 = abstract_matrix<3, 3, int, &vals>;
这仍然可以通过将这些行划分为两个.h文件来改进。例如,您可以使用:
abstract_matrix.h:
#pragma once
#include <cstdint>
template <std::size_t r, std::size_t c, class T , T (*v)[r][c]>
class abstract_matrix
{
public:
static const std::size_t rows = r;
static const std::size_t cols = c;
typedef T value_type;
constexpr static T(&vals)[r][c] = *v;
constexpr abstract_matrix()
{
}
};
id_3by3.h:
#include "abstract_matrix.h"
static int vals[3][3] {
{ 1, 0, 0 },
{ 0, 1, 0 },
{ 0, 0, 1 }
};
using id_3by3 = abstract_matrix<3, 3, int, &vals>;
这将允许您在不同的.h文件中定义类似于id_3by3
的其他类型,而无需在所有文件中复制abstract_matrix
的定义。
相关文章:
- 使用简单类型列表实现的指数编译时间.为什么
- 时间复杂度 当具有复合数据类型(如元组或对)时?
- 标准::时间::d类型的挥发性对象
- 指向(数据)成员的指针作为非类型模板参数,例如具有自动存储持续时间/无链接
- 将结构时间规范添加到类(似乎没有其他类型的)会导致EXEC_BAD_ACCESS
- 无法将 int 类型转换为时间类型(我的类类型)
- C++编译时间类型确定
- 通过引用传递基元类型(如 int、bool)是否比按值传递有任何加速?还是会恶化时间/空间的使用
- C 函数在编译时间返回类型
- 访问和存储/解析性std :: Chrono ::持续时间:: milliseconds(cpprest)时使用什么类型
- 如何恢复注册表项的所有元素?(上次写入时间,类型,值,名称...这是正确的方法吗?
- C++ - 函数中的局部指针变量具有什么类型的存储持续时间以及它们存储在哪里?
- 如何使用谷歌测试打印标准::时间类型
- C 编译时间检查模板类型中是否存在方法
- 在编译时间检查模板参数类型是否设置或多键,并且容器的元素类型是算术的
- 运算符/ STD :: Chrono ::持续时间和自定义类型与Clang
- 编译时间矩阵模板类型
- 类类型的静态constexpr字段在g++中给出链接时间错误
- C 中使用了哪种类型的堆以及STD :: Pirstity_queue的时间复杂性
- STD :: Min of std :: Chrono ::不同类型的持续时间